TianoCore EDK2 master
Loading...
Searching...
No Matches
AhciMode.c
Go to the documentation of this file.
1
11#include "AhciPei.h"
12
13#define ATA_CMD_TRUST_NON_DATA 0x5B
14#define ATA_CMD_TRUST_RECEIVE 0x5C
15#define ATA_CMD_TRUST_SEND 0x5E
16
17//
18// Look up table (IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
19//
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
23};
24
25//
26// Look up table (Lba48Bit, IsIsWrite) for ATA_CMD
27//
28UINT8 mAtaCommands[2][2] = {
29 {
30 ATA_CMD_READ_SECTORS, // 28-bit LBA; PIO read
31 ATA_CMD_WRITE_SECTORS // 28-bit LBA; PIO write
32 },
33 {
34 ATA_CMD_READ_SECTORS_EXT, // 48-bit LBA; PIO read
35 ATA_CMD_WRITE_SECTORS_EXT // 48-bit LBA; PIO write
36 }
37};
38
39//
40// Look up table (IsTrustSend) for ATA_CMD
41//
42UINT8 mAtaTrustCommands[2] = {
43 ATA_CMD_TRUST_RECEIVE, // PIO read
44 ATA_CMD_TRUST_SEND // PIO write
45};
46
47//
48// Look up table (Lba48Bit) for maximum transfer block number
49//
50#define MAX_28BIT_TRANSFER_BLOCK_NUM 0x100
51//
52// Due to limited resource for VTd PEI DMA buffer on platforms, the driver
53// limits the maximum transfer block number for 48-bit addressing.
54// Here, setting to 0x800 means that for device with 512-byte block size, the
55// maximum buffer for DMA mapping will be 1M bytes in size.
56//
57#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x800
58
59UINT32 mMaxTransferBlockNumber[2] = {
60 MAX_28BIT_TRANSFER_BLOCK_NUM,
61 MAX_48BIT_TRANSFER_BLOCK_NUM
62};
63
64//
65// The maximum total sectors count in 28 bit addressing mode
66//
67#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff
68
78UINT32
80 IN UINTN AhciBar,
81 IN UINT32 Offset
82 )
83{
84 UINT32 Data;
85
86 Data = 0;
87 Data = MmioRead32 (AhciBar + Offset);
88
89 return Data;
90}
91
100VOID
102 IN UINTN AhciBar,
103 IN UINT32 Offset,
104 IN UINT32 Data
105 )
106{
107 MmioWrite32 (AhciBar + Offset, Data);
108}
109
118VOID
120 IN UINTN AhciBar,
121 IN UINT32 Offset,
122 IN UINT32 AndData
123 )
124{
125 UINT32 Data;
126
127 Data = AhciReadReg (AhciBar, Offset);
128 Data &= AndData;
129
130 AhciWriteReg (AhciBar, Offset, Data);
131}
132
141VOID
143 IN UINTN AhciBar,
144 IN UINT32 Offset,
145 IN UINT32 OrData
146 )
147{
148 UINT32 Data;
149
150 Data = AhciReadReg (AhciBar, Offset);
151 Data |= OrData;
152
153 AhciWriteReg (AhciBar, Offset, Data);
154}
155
171EFIAPI
173 IN UINTN AhciBar,
174 IN UINT32 Offset,
175 IN UINT32 MaskValue,
176 IN UINT32 TestValue,
177 IN UINT64 Timeout
178 )
179{
180 UINT32 Value;
181 UINT32 Delay;
182
183 Delay = (UINT32)(DivU64x32 (Timeout, 1000) + 1);
184
185 do {
186 Value = AhciReadReg (AhciBar, Offset) & MaskValue;
187
188 if (Value == TestValue) {
189 return EFI_SUCCESS;
190 }
191
192 //
193 // Stall for 100 microseconds.
194 //
195 MicroSecondDelay (100);
196
197 Delay--;
198 } while (Delay > 0);
199
200 return EFI_TIMEOUT;
201}
202
216 IN UINTN Address,
217 IN UINT32 MaskValue,
218 IN UINT32 TestValue
219 )
220{
221 UINT32 Value;
222
223 Value = *(volatile UINT32 *)Address;
224 Value &= MaskValue;
225
226 if (Value == TestValue) {
227 return EFI_SUCCESS;
228 } else {
229 return EFI_NOT_READY;
230 }
231}
232
247 IN EFI_PHYSICAL_ADDRESS Address,
248 IN UINT32 MaskValue,
249 IN UINT32 TestValue,
250 IN UINT64 Timeout
251 )
252{
253 UINT32 Value;
254 UINT64 Delay;
255 BOOLEAN InfiniteWait;
256
257 if (Timeout == 0) {
258 InfiniteWait = TRUE;
259 } else {
260 InfiniteWait = FALSE;
261 }
262
263 Delay = DivU64x32 (Timeout, 1000) + 1;
264
265 do {
266 //
267 // Access system memory to see if the value is the tested one.
268 //
269 // The system memory pointed by Address will be updated by the
270 // SATA Host Controller, "volatile" is introduced to prevent
271 // compiler from optimizing the access to the memory address
272 // to only read once.
273 //
274 Value = *(volatile UINT32 *)(UINTN)Address;
275 Value &= MaskValue;
276
277 if (Value == TestValue) {
278 return EFI_SUCCESS;
279 }
280
281 //
282 // Stall for 100 microseconds.
283 //
284 MicroSecondDelay (100);
285
286 Delay--;
287 } while (InfiniteWait || (Delay > 0));
288
289 return EFI_TIMEOUT;
290}
291
301VOID
303 IN UINTN AhciBar,
304 IN UINT8 Port
305 )
306{
307 UINT32 Offset;
308
309 //
310 // Clear any error status
311 //
312 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
313 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
314
315 //
316 // Clear any port interrupt status
317 //
318 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IS;
319 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
320
321 //
322 // Clear any HBA interrupt status
323 //
324 AhciWriteReg (AhciBar, AHCI_IS_OFFSET, AhciReadReg (AhciBar, AHCI_IS_OFFSET));
325}
326
341 IN UINTN AhciBar,
342 IN UINT8 Port,
343 IN UINT64 Timeout
344 )
345{
346 UINT32 Offset;
347
348 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
349 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
350
351 return EFI_SUCCESS;
352}
353
369 IN UINTN AhciBar,
370 IN UINT8 Port,
371 IN UINT64 Timeout
372 )
373{
374 UINT32 Offset;
375 UINT32 Data;
376
377 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
378 Data = AhciReadReg (AhciBar, Offset);
379
380 //
381 // Before disabling Fis receive, the DMA engine of the port should NOT be in
382 // running status.
383 //
384 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) != 0) {
385 return EFI_UNSUPPORTED;
386 }
387
388 //
389 // Check if the Fis receive DMA engine for the port is running.
390 //
391 if ((Data & AHCI_PORT_CMD_FR) != AHCI_PORT_CMD_FR) {
392 return EFI_SUCCESS;
393 }
394
395 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_FRE));
396
397 return AhciWaitMmioSet (
398 AhciBar,
399 Offset,
400 AHCI_PORT_CMD_FR,
401 0,
402 Timeout
403 );
404}
405
421VOID
424 IN UINT8 Port,
425 IN UINT8 PortMultiplier,
426 IN UINT8 FisIndex,
427 IN EFI_AHCI_COMMAND_FIS *CommandFis,
428 IN EFI_AHCI_COMMAND_LIST *CommandList,
429 IN UINT8 CommandSlotNumber,
430 IN OUT VOID *DataPhysicalAddr,
431 IN UINT32 DataLength
432 )
433{
434 EFI_AHCI_REGISTERS *AhciRegisters;
435 UINTN AhciBar;
436 UINT64 BaseAddr;
437 UINT32 PrdtNumber;
438 UINT32 PrdtIndex;
439 UINTN RemainedData;
440 UINTN MemAddr;
441 DATA_64 Data64;
442 UINT32 Offset;
443
444 AhciRegisters = &Private->AhciRegisters;
445 AhciBar = Private->MmioBase;
446
447 //
448 // Filling the PRDT
449 //
450 PrdtNumber = (UINT32)DivU64x32 (
451 (UINT64)DataLength + AHCI_MAX_DATA_PER_PRDT - 1,
452 AHCI_MAX_DATA_PER_PRDT
453 );
454
455 //
456 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
457 // It also limits that the maximum amount of the PRDT entry in the command table
458 // is 65535.
459 // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
460 // PRDT entries.
461 //
462 ASSERT (PrdtNumber <= AHCI_MAX_PRDT_NUMBER);
463 if (PrdtNumber > AHCI_MAX_PRDT_NUMBER) {
464 return;
465 }
466
467 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
468
469 BaseAddr = Data64.Uint64;
470
471 ZeroMem ((VOID *)((UINTN)BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
472
473 ZeroMem (AhciRegisters->AhciCmdTable, sizeof (EFI_AHCI_COMMAND_TABLE));
474
475 CommandFis->AhciCFisPmNum = PortMultiplier;
476
477 CopyMem (&AhciRegisters->AhciCmdTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
478
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));
481
482 RemainedData = (UINTN)DataLength;
483 MemAddr = (UINTN)DataPhysicalAddr;
484 CommandList->AhciCmdPrdtl = PrdtNumber;
485
486 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
487 if (RemainedData < AHCI_MAX_DATA_PER_PRDT) {
488 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
489 } else {
490 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = AHCI_MAX_DATA_PER_PRDT - 1;
491 }
492
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;
498 }
499
500 //
501 // Set the last PRDT to Interrupt On Complete
502 //
503 if (PrdtNumber > 0) {
504 AhciRegisters->AhciCmdTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
505 }
506
507 CopyMem (
508 (VOID *)((UINTN)AhciRegisters->AhciCmdList + (UINTN)CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
509 CommandList,
510 sizeof (EFI_AHCI_COMMAND_LIST)
511 );
512
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;
517}
518
528VOID
531 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
532 )
533{
534 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
535
536 CmdFis->AhciCFisType = AHCI_FIS_REGISTER_H2D;
537 //
538 // Indicator it's a command
539 //
540 CmdFis->AhciCFisCmdInd = 0x1;
541 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
542
543 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
544 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
545
546 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
547 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
548
549 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
550 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
551
552 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
553 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
554
555 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
556 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
557
558 CmdFis->AhciCFisDevHead = (UINT8)(AtaCommandBlock->AtaDeviceHead | 0xE0);
559}
560
575 IN UINTN AhciBar,
576 IN UINT8 Port,
577 IN UINT64 Timeout
578 )
579{
580 UINT32 Offset;
581 UINT32 Data;
582
583 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
584 Data = AhciReadReg (AhciBar, Offset);
585
586 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) == 0) {
587 return EFI_SUCCESS;
588 }
589
590 if ((Data & AHCI_PORT_CMD_ST) != 0) {
591 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_ST));
592 }
593
594 return AhciWaitMmioSet (
595 AhciBar,
596 Offset,
597 AHCI_PORT_CMD_CR,
598 0,
599 Timeout
600 );
601}
602
618 IN UINTN AhciBar,
619 IN UINT8 Port,
620 IN UINT8 CommandSlot,
621 IN UINT64 Timeout
622 )
623{
624 UINT32 CmdSlotBit;
625 EFI_STATUS Status;
626 UINT32 PortStatus;
627 UINT32 StartCmd;
628 UINT32 PortTfd;
629 UINT32 Offset;
630 UINT32 Capability;
631
632 //
633 // Collect AHCI controller information
634 //
635 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
636
637 CmdSlotBit = (UINT32)(1 << CommandSlot);
638
640 AhciBar,
641 Port
642 );
643
644 Status = AhciEnableFisReceive (
645 AhciBar,
646 Port,
647 Timeout
648 );
649 if (EFI_ERROR (Status)) {
650 return Status;
651 }
652
653 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
654 PortStatus = AhciReadReg (AhciBar, Offset);
655
656 StartCmd = 0;
657 if ((PortStatus & AHCI_PORT_CMD_ALPE) != 0) {
658 StartCmd = AhciReadReg (AhciBar, Offset);
659 StartCmd &= ~AHCI_PORT_CMD_ICC_MASK;
660 StartCmd |= AHCI_PORT_CMD_ACTIVE;
661 }
662
663 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
664 PortTfd = AhciReadReg (AhciBar, Offset);
665
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);
670
672 AhciBar,
673 Offset,
674 AHCI_PORT_CMD_CLO,
675 0,
676 Timeout
677 );
678 }
679 }
680
681 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
682 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_ST | StartCmd);
683
684 //
685 // Setting the command
686 //
687 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CI;
688 AhciAndReg (AhciBar, Offset, 0);
689 AhciOrReg (AhciBar, Offset, CmdSlotBit);
690
691 return EFI_SUCCESS;
692}
693
719 IN UINT8 Port,
720 IN UINT8 PortMultiplier,
721 IN UINT8 FisIndex,
722 IN BOOLEAN Read,
723 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
724 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
725 IN OUT VOID *MemoryAddr,
726 IN UINT32 DataCount,
727 IN UINT64 Timeout
728 )
729{
730 EFI_STATUS Status;
732 UINTN MapLength;
733 EFI_PHYSICAL_ADDRESS PhyAddr;
734 VOID *MapData;
735 EFI_AHCI_REGISTERS *AhciRegisters;
736 UINTN AhciBar;
737 BOOLEAN InfiniteWait;
738 UINT32 Offset;
739 UINT32 OldRfisLo;
740 UINT32 OldRfisHi;
741 UINT32 OldCmdListLo;
742 UINT32 OldCmdListHi;
743 DATA_64 Data64;
744 UINT32 FisBaseAddr;
745 UINT32 Delay;
747 EFI_AHCI_COMMAND_LIST CmdList;
748 UINT32 PortTfd;
749 UINT32 PrdCount;
750 BOOLEAN PioFisReceived;
751 BOOLEAN D2hFisReceived;
752
753 //
754 // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
755 // PRDT entries.
756 //
757 if (DataCount / (UINT32)AHCI_MAX_PRDT_NUMBER > AHCI_MAX_DATA_PER_PRDT) {
758 DEBUG ((
759 DEBUG_ERROR,
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",
762 __func__,
763 AHCI_MAX_PRDT_NUMBER,
764 DataCount,
765 AHCI_MAX_PRDT_NUMBER * AHCI_MAX_DATA_PER_PRDT
766 ));
767 return EFI_UNSUPPORTED;
768 }
769
770 MapOp = Read ? EdkiiIoMmuOperationBusMasterWrite :
772 MapLength = DataCount;
773 Status = IoMmuMap (
774 MapOp,
775 MemoryAddr,
776 &MapLength,
777 &PhyAddr,
778 &MapData
779 );
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;
783 }
784
785 AhciRegisters = &Private->AhciRegisters;
786 AhciBar = Private->MmioBase;
787 InfiniteWait = (Timeout == 0) ? TRUE : FALSE;
788
789 //
790 // Fill FIS base address register
791 //
792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
793 OldRfisLo = AhciReadReg (AhciBar, Offset);
794 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
795 OldRfisHi = AhciReadReg (AhciBar, Offset);
796 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
797 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
798 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
800 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
801
802 //
803 // Single task environment, we only use one command table for all port
804 //
805 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
806 OldCmdListLo = AhciReadReg (AhciBar, Offset);
807 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
808 OldCmdListHi = AhciReadReg (AhciBar, Offset);
809 Data64.Uint64 = (UINTN)(AhciRegisters->AhciCmdList);
810 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
811 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
812 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
813 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
814
815 //
816 // Package read needed
817 //
818 AhciBuildCommandFis (&CFis, AtaCommandBlock);
819
820 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
821
822 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
823 CmdList.AhciCmdW = Read ? 0 : 1;
824
826 Private,
827 Port,
828 PortMultiplier,
829 FisIndex,
830 &CFis,
831 &CmdList,
832 0,
833 (VOID *)(UINTN)PhyAddr,
834 DataCount
835 );
836
837 Status = AhciStartCommand (
838 AhciBar,
839 Port,
840 0,
841 Timeout
842 );
843 if (EFI_ERROR (Status)) {
844 goto Exit;
845 }
846
847 //
848 // Checking the status and wait the driver sending Data
849 //
850 FisBaseAddr = (UINT32)(UINTN)AhciRegisters->AhciRFis + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
851 if (Read) {
852 //
853 // Wait device sends the PIO setup fis before data transfer
854 //
855 Status = EFI_TIMEOUT;
856 Delay = (UINT32)DivU64x32 (Timeout, 1000) + 1;
857 do {
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;
865 }
866
867 //
868 // According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered.
869 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from
870 // device after the transaction is finished successfully.
871 // To get better device compatibilities, we further check if the PxTFD's
872 // ERR bit is set. By this way, we can know if there is a real error happened.
873 //
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;
879 }
880
881 if (PioFisReceived || D2hFisReceived) {
882 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
883 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
884 //
885 // PxTFD will be updated if there is a D2H or SetupFIS received.
886 //
887 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
888 Status = EFI_DEVICE_ERROR;
889 break;
890 }
891
892 PrdCount = *(volatile UINT32 *)(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
893 if (PrdCount == DataCount) {
894 Status = EFI_SUCCESS;
895 break;
896 }
897 }
898
899 //
900 // Stall for 100 microseconds.
901 //
902 MicroSecondDelay (100);
903
904 Delay--;
905 if (Delay == 0) {
906 Status = EFI_TIMEOUT;
907 }
908 } while (InfiniteWait || (Delay > 0));
909 } else {
910 //
911 // Wait for D2H Fis is received
912 //
913 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
914 Status = AhciWaitMemSet (
915 Offset,
916 AHCI_FIS_TYPE_MASK,
917 AHCI_FIS_REGISTER_D2H,
918 Timeout
919 );
920 if (EFI_ERROR (Status)) {
921 DEBUG ((DEBUG_ERROR, "%a: AhciWaitMemSet (%r)\n", __func__, Status));
922 goto Exit;
923 }
924
925 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
926 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
927 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
928 Status = EFI_DEVICE_ERROR;
929 }
930 }
931
932Exit:
934 AhciBar,
935 Port,
936 Timeout
937 );
938
940 AhciBar,
941 Port,
942 Timeout
943 );
944
945 if (MapData != NULL) {
946 IoMmuUnmap (MapData);
947 }
948
949 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
950 AhciWriteReg (AhciBar, Offset, OldRfisLo);
951 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
952 AhciWriteReg (AhciBar, Offset, OldRfisHi);
953
954 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
955 AhciWriteReg (AhciBar, Offset, OldCmdListLo);
956 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
957 AhciWriteReg (AhciBar, Offset, OldCmdListHi);
958
959 return Status;
960}
961
983 IN UINT8 Port,
984 IN UINT8 PortMultiplier,
985 IN UINT8 FisIndex,
986 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
987 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
988 IN UINT64 Timeout
989 )
990{
991 EFI_STATUS Status;
992 UINTN AhciBar;
993 EFI_AHCI_REGISTERS *AhciRegisters;
994 UINTN FisBaseAddr;
995 UINTN Offset;
996 UINT32 PortTfd;
998 EFI_AHCI_COMMAND_LIST CmdList;
999
1000 AhciBar = Private->MmioBase;
1001 AhciRegisters = &Private->AhciRegisters;
1002
1003 //
1004 // Package read needed
1005 //
1006 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1007
1008 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1009
1010 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1011
1013 Private,
1014 Port,
1015 PortMultiplier,
1016 FisIndex,
1017 &CFis,
1018 &CmdList,
1019 0,
1020 NULL,
1021 0
1022 );
1023
1024 Status = AhciStartCommand (
1025 AhciBar,
1026 Port,
1027 0,
1028 Timeout
1029 );
1030 if (EFI_ERROR (Status)) {
1031 goto Exit;
1032 }
1033
1034 //
1035 // Wait device sends the Response Fis
1036 //
1037 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
1038 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
1039 Status = AhciWaitMemSet (
1040 Offset,
1041 AHCI_FIS_TYPE_MASK,
1042 AHCI_FIS_REGISTER_D2H,
1043 Timeout
1044 );
1045
1046 if (EFI_ERROR (Status)) {
1047 goto Exit;
1048 }
1049
1050 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1051 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
1052 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
1053 Status = EFI_DEVICE_ERROR;
1054 }
1055
1056Exit:
1058 AhciBar,
1059 Port,
1060 Timeout
1061 );
1062
1064 AhciBar,
1065 Port,
1066 Timeout
1067 );
1068
1069 return Status;
1070}
1071
1085 IN UINTN AhciBar,
1086 IN UINT64 Timeout
1087 )
1088{
1089 UINT32 Delay;
1090 UINT32 Value;
1091 UINT32 Capability;
1092
1093 //
1094 // Collect AHCI controller information
1095 //
1096 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1097
1098 //
1099 // Enable AE before accessing any AHCI registers if Supports AHCI Mode Only is not set
1100 //
1101 if ((Capability & AHCI_CAP_SAM) == 0) {
1102 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1103 }
1104
1105 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_RESET);
1106
1107 Delay = (UINT32)(DivU64x32 (Timeout, 1000) + 1);
1108
1109 do {
1110 Value = AhciReadReg (AhciBar, AHCI_GHC_OFFSET);
1111 if ((Value & AHCI_GHC_RESET) == 0) {
1112 return EFI_SUCCESS;
1113 }
1114
1115 //
1116 // Stall for 100 microseconds.
1117 //
1118 MicroSecondDelay (100);
1119
1120 Delay--;
1121 } while (Delay > 0);
1122
1123 return EFI_TIMEOUT;
1124}
1125
1145 IN UINT8 Port,
1146 IN UINT8 PortMultiplier,
1147 IN UINT8 FisIndex,
1148 IN ATA_IDENTIFY_DATA *Buffer
1149 )
1150{
1151 EFI_STATUS Status;
1154
1155 if (Buffer == NULL) {
1156 return EFI_INVALID_PARAMETER;
1157 }
1158
1159 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
1160 ZeroMem (&Asb, sizeof (EFI_ATA_STATUS_BLOCK));
1161
1162 Acb.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1163 Acb.AtaSectorCount = 1;
1164
1165 Status = AhciPioTransfer (
1166 Private,
1167 Port,
1168 PortMultiplier,
1169 FisIndex,
1170 TRUE,
1171 &Acb,
1172 &Asb,
1173 Buffer,
1174 sizeof (ATA_IDENTIFY_DATA),
1175 ATA_TIMEOUT
1176 );
1177
1178 return Status;
1179}
1180
1189UINT8
1191 IN UINT32 PortBitMap
1192 )
1193{
1194 UINT8 NumberOfPorts;
1195
1196 NumberOfPorts = 0;
1197
1198 while (PortBitMap != 0) {
1199 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1200 NumberOfPorts++;
1201 }
1202
1203 PortBitMap = PortBitMap >> 1;
1204 }
1205
1206 return NumberOfPorts;
1207}
1208
1223 IN UINT32 PortBitMap,
1224 IN UINT8 PortIndex,
1225 OUT UINT8 *Port
1226 )
1227{
1228 if (PortIndex == 0) {
1229 return EFI_NOT_FOUND;
1230 }
1231
1232 *Port = 0;
1233
1234 while (PortBitMap != 0) {
1235 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1236 PortIndex--;
1237
1238 //
1239 // Found the port specified by PortIndex.
1240 //
1241 if (PortIndex == 0) {
1242 return EFI_SUCCESS;
1243 }
1244 }
1245
1246 PortBitMap = PortBitMap >> 1;
1247 *Port = *Port + 1;
1248 }
1249
1250 return EFI_NOT_FOUND;
1251}
1252
1265 )
1266{
1267 EFI_STATUS Status;
1268 UINTN AhciBar;
1269 EFI_AHCI_REGISTERS *AhciRegisters;
1270 EFI_PHYSICAL_ADDRESS DeviceAddress;
1271 VOID *Base;
1272 VOID *Mapping;
1273 UINT32 Capability;
1274 UINT32 PortImplementBitMap;
1275 UINT8 MaxPortNumber;
1276 UINT8 MaxCommandSlotNumber;
1277 UINTN MaxRFisSize;
1278 UINTN MaxCmdListSize;
1279 UINTN MaxCmdTableSize;
1280
1281 AhciBar = Private->MmioBase;
1282 AhciRegisters = &Private->AhciRegisters;
1283
1284 //
1285 // Collect AHCI controller information
1286 //
1287 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1288
1289 //
1290 // Get the number of command slots per port supported by this HBA.
1291 //
1292 MaxCommandSlotNumber = (UINT8)(((Capability & 0x1F00) >> 8) + 1);
1293 ASSERT (MaxCommandSlotNumber > 0);
1294 if (MaxCommandSlotNumber == 0) {
1295 return EFI_DEVICE_ERROR;
1296 }
1297
1298 //
1299 // Get the highest bit of implemented ports which decides how many bytes are
1300 // allocated for recived FIS.
1301 //
1302 PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1303 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32 (PortImplementBitMap) + 1);
1304 if (MaxPortNumber == 0) {
1305 return EFI_DEVICE_ERROR;
1306 }
1307
1308 //
1309 // Get the number of ports that actually needed to be initialized.
1310 //
1311 MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1312
1313 //
1314 // Allocate memory for received FIS.
1315 //
1316 MaxRFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
1317 Status = IoMmuAllocateBuffer (
1318 EFI_SIZE_TO_PAGES (MaxRFisSize),
1319 &Base,
1320 &DeviceAddress,
1321 &Mapping
1322 );
1323 if (EFI_ERROR (Status)) {
1324 return EFI_OUT_OF_RESOURCES;
1325 }
1326
1327 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1328 AhciRegisters->AhciRFis = Base;
1329 AhciRegisters->AhciRFisMap = Mapping;
1330 AhciRegisters->MaxRFisSize = MaxRFisSize;
1331 ZeroMem (AhciRegisters->AhciRFis, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxRFisSize));
1332
1333 //
1334 // Allocate memory for command list.
1335 // Note that the implemenation is a single task model which only use a command
1336 // list for each port.
1337 //
1338 MaxCmdListSize = 1 * sizeof (EFI_AHCI_COMMAND_LIST);
1339 Status = IoMmuAllocateBuffer (
1340 EFI_SIZE_TO_PAGES (MaxCmdListSize),
1341 &Base,
1342 &DeviceAddress,
1343 &Mapping
1344 );
1345 if (EFI_ERROR (Status)) {
1346 Status = EFI_OUT_OF_RESOURCES;
1347 goto ErrorExit;
1348 }
1349
1350 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1351 AhciRegisters->AhciCmdList = Base;
1352 AhciRegisters->AhciCmdListMap = Mapping;
1353 AhciRegisters->MaxCmdListSize = MaxCmdListSize;
1354 ZeroMem (AhciRegisters->AhciCmdList, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdListSize));
1355
1356 //
1357 // Allocate memory for command table
1358 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
1359 //
1360 MaxCmdTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
1361 Status = IoMmuAllocateBuffer (
1362 EFI_SIZE_TO_PAGES (MaxCmdTableSize),
1363 &Base,
1364 &DeviceAddress,
1365 &Mapping
1366 );
1367 if (EFI_ERROR (Status)) {
1368 Status = EFI_OUT_OF_RESOURCES;
1369 goto ErrorExit;
1370 }
1371
1372 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1373 AhciRegisters->AhciCmdTable = Base;
1374 AhciRegisters->AhciCmdTableMap = Mapping;
1375 AhciRegisters->MaxCmdTableSize = MaxCmdTableSize;
1376 ZeroMem (AhciRegisters->AhciCmdTable, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdTableSize));
1377
1378 return EFI_SUCCESS;
1379
1380ErrorExit:
1381 if (AhciRegisters->AhciRFisMap != NULL) {
1383 EFI_SIZE_TO_PAGES (AhciRegisters->MaxRFisSize),
1384 AhciRegisters->AhciRFis,
1385 AhciRegisters->AhciRFisMap
1386 );
1387 AhciRegisters->AhciRFis = NULL;
1388 }
1389
1390 if (AhciRegisters->AhciCmdListMap != NULL) {
1392 EFI_SIZE_TO_PAGES (AhciRegisters->MaxCmdListSize),
1393 AhciRegisters->AhciCmdList,
1394 AhciRegisters->AhciCmdListMap
1395 );
1396 AhciRegisters->AhciCmdList = NULL;
1397 }
1398
1399 return Status;
1400}
1401
1414EFI_LBA
1416 IN ATA_IDENTIFY_DATA *IdentifyData
1417 )
1418{
1419 EFI_LBA Capacity;
1420 EFI_LBA TmpLba;
1421 UINTN Index;
1422
1423 if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
1424 //
1425 // The device doesn't support 48 bit addressing
1426 //
1427 return 0;
1428 }
1429
1430 //
1431 // 48 bit address feature set is supported, get maximum capacity
1432 //
1433 Capacity = 0;
1434 for (Index = 0; Index < 4; Index++) {
1435 //
1436 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
1437 //
1438 TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
1439 Capacity |= LShiftU64 (TmpLba, 16 * Index);
1440 }
1441
1442 return Capacity;
1443}
1444
1466 IN OUT PEI_AHCI_ATA_DEVICE_DATA *DeviceData
1467 )
1468{
1469 ATA_IDENTIFY_DATA *IdentifyData;
1471 EFI_LBA Capacity;
1472 UINT32 MaxSectorCount;
1473 UINT16 PhyLogicSectorSupport;
1474
1475 IdentifyData = DeviceData->IdentifyData;
1476 Media = &DeviceData->Media;
1477
1478 if ((IdentifyData->config & BIT15) != 0) {
1479 DEBUG ((
1480 DEBUG_ERROR,
1481 "%a: Not a hard disk device on Port 0x%x PortMultiplierPort 0x%x\n",
1482 __func__,
1483 DeviceData->Port,
1484 DeviceData->PortMultiplier
1485 ));
1486 return EFI_UNSUPPORTED;
1487 }
1488
1489 DEBUG ((
1490 DEBUG_INFO,
1491 "%a: Identify Device: Port 0x%x PortMultiplierPort 0x%x\n",
1492 __func__,
1493 DeviceData->Port,
1494 DeviceData->PortMultiplier
1495 ));
1496
1497 //
1498 // Skip checking whether the WORD 88 (supported UltraDMA by drive), since the
1499 // driver only support PIO data transfer for now.
1500 //
1501
1502 //
1503 // Get the capacity information of the device.
1504 //
1505 Capacity = GetAtapi6Capacity (IdentifyData);
1506 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
1507 //
1508 // Capacity exceeds 120GB. 48-bit addressing is really needed
1509 //
1510 DeviceData->Lba48Bit = TRUE;
1511 } else {
1512 //
1513 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
1514 //
1515 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) |
1516 IdentifyData->user_addressable_sectors_lo;
1517 DeviceData->Lba48Bit = FALSE;
1518 }
1519
1520 if (Capacity == 0) {
1521 DEBUG ((DEBUG_ERROR, "%a: Invalid Capacity (0) for ATA device.\n", __func__));
1522 return EFI_UNSUPPORTED;
1523 }
1524
1525 Media->LastBlock = (EFI_PEI_LBA)(Capacity - 1);
1526
1527 Media->BlockSize = 0x200;
1528 //
1529 // Check whether Long Physical Sector Feature is supported
1530 //
1531 PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
1532 DEBUG ((
1533 DEBUG_INFO,
1534 "%a: PhyLogicSectorSupport = 0x%x\n",
1535 __func__,
1536 PhyLogicSectorSupport
1537 ));
1538 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
1539 //
1540 // Check logical block size
1541 //
1542 if ((PhyLogicSectorSupport & BIT12) != 0) {
1543 Media->BlockSize = (UINT32)(((IdentifyData->logic_sector_size_hi << 16) |
1544 IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
1545 }
1546 }
1547
1548 //
1549 // Check BlockSize validity
1550 //
1551 MaxSectorCount = mMaxTransferBlockNumber[DeviceData->Lba48Bit];
1552 if ((Media->BlockSize == 0) || (Media->BlockSize > MAX_UINT32 / MaxSectorCount)) {
1553 DEBUG ((DEBUG_ERROR, "%a: Invalid BlockSize (0x%x).\n", __func__, Media->BlockSize));
1554 return EFI_UNSUPPORTED;
1555 }
1556
1557 DEBUG ((
1558 DEBUG_INFO,
1559 "%a: BlockSize = 0x%x, LastBlock = 0x%lx\n",
1560 __func__,
1561 Media->BlockSize,
1562 Media->LastBlock
1563 ));
1564
1565 if ((IdentifyData->trusted_computing_support & BIT0) != 0) {
1566 DEBUG ((DEBUG_INFO, "%a: Found Trust Computing feature support.\n", __func__));
1567 DeviceData->TrustComputing = TRUE;
1568 }
1569
1570 Media->InterfaceType = MSG_SATA_DP;
1571 Media->RemovableMedia = FALSE;
1572 Media->MediaPresent = TRUE;
1573 Media->ReadOnly = FALSE;
1574
1575 return EFI_SUCCESS;
1576}
1577
1604 IN UINTN DeviceIndex,
1605 IN UINT16 Port,
1606 IN UINT16 PortMultiplier,
1607 IN UINT8 FisIndex,
1608 IN ATA_IDENTIFY_DATA *IdentifyData
1609 )
1610{
1611 PEI_AHCI_ATA_DEVICE_DATA *DeviceData;
1612 EFI_STATUS Status;
1613
1614 DeviceData = AllocateZeroPool (sizeof (PEI_AHCI_ATA_DEVICE_DATA));
1615 if (DeviceData == NULL) {
1616 return EFI_OUT_OF_RESOURCES;
1617 }
1618
1619 if (IdentifyData != NULL) {
1620 DeviceData->IdentifyData = AllocateCopyPool (sizeof (ATA_IDENTIFY_DATA), IdentifyData);
1621 if (DeviceData->IdentifyData == NULL) {
1622 return EFI_OUT_OF_RESOURCES;
1623 }
1624 }
1625
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;
1632
1633 Status = IdentifyAtaDevice (DeviceData);
1634 if (EFI_ERROR (Status)) {
1635 return Status;
1636 }
1637
1638 if (DeviceData->TrustComputing) {
1639 Private->TrustComputingDevices++;
1640 DeviceData->TrustComputingDeviceIndex = Private->TrustComputingDevices;
1641 }
1642
1643 Private->ActiveDevices++;
1644 InsertTailList (&Private->DeviceList, &DeviceData->Link);
1645
1646 return EFI_SUCCESS;
1647}
1648
1666 )
1667{
1668 EFI_STATUS Status;
1669 UINTN AhciBar;
1670 UINT32 Capability;
1671 UINT32 Value;
1672 UINT8 MaxPortNumber;
1673 UINT32 PortImplementBitMap;
1674 UINT32 PortInitializeBitMap;
1675 EFI_AHCI_REGISTERS *AhciRegisters;
1676 UINT8 PortIndex;
1677 UINT8 Port;
1678 DATA_64 Data64;
1679 UINT32 Data;
1680 UINT32 Offset;
1681 UINT32 PhyDetectDelay;
1682 UINTN DeviceIndex;
1683 ATA_IDENTIFY_DATA IdentifyData;
1684
1685 AhciBar = Private->MmioBase;
1686
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;
1691 }
1692
1693 //
1694 // Collect AHCI controller information
1695 //
1696 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1697
1698 //
1699 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1700 //
1701 Value = AhciReadReg (AhciBar, AHCI_GHC_OFFSET);
1702 if ((Value & AHCI_GHC_ENABLE) == 0) {
1703 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1704 }
1705
1706 Status = AhciCreateTransferDescriptor (Private);
1707 if (EFI_ERROR (Status)) {
1708 DEBUG ((
1709 DEBUG_ERROR,
1710 "%a: Transfer-related data allocation failed with %r.\n",
1711 __func__,
1712 Status
1713 ));
1714 return EFI_OUT_OF_RESOURCES;
1715 }
1716
1717 //
1718 // Get the number of command slots per port supported by this HBA.
1719 //
1720 MaxPortNumber = (UINT8)((Capability & 0x1F) + 1);
1721
1722 //
1723 // Get the bit map of those ports exposed by this HBA.
1724 // It indicates which ports that the HBA supports are available for software
1725 // to use.
1726 //
1727 PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1728
1729 //
1730 // Get the number of ports that actually needed to be initialized.
1731 //
1732 MaxPortNumber = MIN (MaxPortNumber, (UINT8)(UINTN)(HighBitSet32 (PortImplementBitMap) + 1));
1733 MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1734
1735 PortInitializeBitMap = Private->PortBitMap & PortImplementBitMap;
1736 AhciRegisters = &Private->AhciRegisters;
1737 DeviceIndex = 0;
1738 //
1739 // Enumerate ATA ports
1740 //
1741 for (PortIndex = 1; PortIndex <= MaxPortNumber; PortIndex++) {
1742 Status = AhciGetPortFromMap (PortInitializeBitMap, PortIndex, &Port);
1743 if (EFI_ERROR (Status)) {
1744 //
1745 // No more available port, just break out of the loop.
1746 //
1747 break;
1748 }
1749
1750 if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
1751 //
1752 // Initialize FIS Base Address Register and Command List Base Address
1753 // Register for use.
1754 //
1755 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) +
1756 sizeof (EFI_AHCI_RECEIVED_FIS) * (PortIndex - 1);
1757 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
1758 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1759 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
1760 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1761
1762 Data64.Uint64 = (UINTN)(AhciRegisters->AhciCmdList);
1763 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
1764 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1765 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
1766 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1767
1768 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1769 Data = AhciReadReg (AhciBar, Offset);
1770 if ((Data & AHCI_PORT_CMD_CPD) != 0) {
1771 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_POD);
1772 }
1773
1774 if ((Capability & AHCI_CAP_SSS) != 0) {
1775 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_SUD);
1776 }
1777
1778 //
1779 // Disable aggressive power management.
1780 //
1781 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SCTL;
1782 AhciOrReg (AhciBar, Offset, AHCI_PORT_SCTL_IPM_INIT);
1783 //
1784 // Disable the reporting of the corresponding interrupt to system software.
1785 //
1786 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IE;
1787 AhciAndReg (AhciBar, Offset, 0);
1788
1789 //
1790 // Enable FIS Receive DMA engine for the first D2H FIS.
1791 //
1792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1793 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
1794
1795 //
1796 // Wait no longer than 15 ms to wait the Phy to detect the presence of a device.
1797 //
1798 PhyDetectDelay = AHCI_BUS_PHY_DETECT_TIMEOUT;
1799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SSTS;
1800 do {
1801 Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_SSTS_DET_MASK;
1802 if ((Data == AHCI_PORT_SSTS_DET_PCE) || (Data == AHCI_PORT_SSTS_DET)) {
1803 break;
1804 }
1805
1806 MicroSecondDelay (1000);
1807 PhyDetectDelay--;
1808 } while (PhyDetectDelay > 0);
1809
1810 if (PhyDetectDelay == 0) {
1811 //
1812 // No device detected at this port.
1813 // Clear PxCMD.SUD for those ports at which there are no device present.
1814 //
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));
1818 continue;
1819 }
1820
1821 //
1822 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
1823 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
1824 //
1825 PhyDetectDelay = 16 * 1000;
1826 do {
1827 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
1828 if (AhciReadReg (AhciBar, Offset) != 0) {
1829 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
1830 }
1831
1832 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1833
1834 Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_TFD_MASK;
1835 if (Data == 0) {
1836 break;
1837 }
1838
1839 MicroSecondDelay (1000);
1840 PhyDetectDelay--;
1841 } while (PhyDetectDelay > 0);
1842
1843 if (PhyDetectDelay == 0) {
1844 DEBUG ((
1845 DEBUG_ERROR,
1846 "%a: Port %d device presence detected but phy not ready (TFD=0x%x).\n",
1847 __func__,
1848 Port,
1849 Data
1850 ));
1851 continue;
1852 }
1853
1854 //
1855 // When the first D2H register FIS is received, the content of PxSIG register is updated.
1856 //
1857 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SIG;
1858 Status = AhciWaitMmioSet (
1859 AhciBar,
1860 Offset,
1861 0x0000FFFF,
1862 0x00000101,
1863 160000000
1864 );
1865 if (EFI_ERROR (Status)) {
1866 DEBUG ((
1867 DEBUG_ERROR,
1868 "%a: Error occurred when waiting for the first D2H register FIS - %r\n",
1869 __func__,
1870 Status
1871 ));
1872 continue;
1873 }
1874
1875 Data = AhciReadReg (AhciBar, Offset);
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));
1880 continue;
1881 }
1882
1883 DEBUG ((DEBUG_INFO, "%a: ATA hard disk found on Port %d.\n", __func__, Port));
1884 } else {
1885 continue;
1886 }
1887
1888 //
1889 // Found an ATA hard disk device, add it into the device list.
1890 //
1891 DeviceIndex++;
1893 Private,
1894 DeviceIndex,
1895 Port,
1896 0xFFFF,
1897 PortIndex - 1,
1898 &IdentifyData
1899 );
1900 }
1901 }
1902
1903 return EFI_SUCCESS;
1904}
1905
1925 IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData,
1926 IN OUT VOID *Buffer,
1927 IN EFI_LBA StartLba,
1928 IN UINT32 TransferLength,
1929 IN BOOLEAN IsWrite
1930 )
1931{
1933 EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru;
1936
1937 Private = DeviceData->Private;
1938 AtaPassThru = &Private->AtaPassThruPpi;
1939
1940 //
1941 // Ensure Lba48Bit and IsWrite are valid boolean values
1942 //
1943 ASSERT ((UINTN)DeviceData->Lba48Bit < 2);
1944 ASSERT ((UINTN)IsWrite < 2);
1945 if (((UINTN)DeviceData->Lba48Bit >= 2) ||
1946 ((UINTN)IsWrite >= 2))
1947 {
1948 return EFI_INVALID_PARAMETER;
1949 }
1950
1951 //
1952 // Prepare for ATA command block.
1953 //
1954 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
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);
1968 } else {
1969 Acb.AtaDeviceHead = (UINT8)(Acb.AtaDeviceHead | RShiftU64 (StartLba, 24));
1970 }
1971
1972 //
1973 // Prepare for ATA pass through packet.
1974 //
1975 ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
1976 if (IsWrite) {
1977 Packet.OutDataBuffer = Buffer;
1978 Packet.OutTransferLength = TransferLength;
1979 } else {
1980 Packet.InDataBuffer = Buffer;
1981 Packet.InTransferLength = TransferLength;
1982 }
1983
1984 Packet.Asb = NULL;
1985 Packet.Acb = &Acb;
1986 Packet.Protocol = mAtaPassThruCmdProtocols[IsWrite];
1987 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
1988 //
1989 // |------------------------|-----------------|
1990 // | ATA PIO Transfer Mode | Transfer Rate |
1991 // |------------------------|-----------------|
1992 // | PIO Mode 0 | 3.3Mbytes/sec |
1993 // |------------------------|-----------------|
1994 // | PIO Mode 1 | 5.2Mbytes/sec |
1995 // |------------------------|-----------------|
1996 // | PIO Mode 2 | 8.3Mbytes/sec |
1997 // |------------------------|-----------------|
1998 // | PIO Mode 3 | 11.1Mbytes/sec |
1999 // |------------------------|-----------------|
2000 // | PIO Mode 4 | 16.6Mbytes/sec |
2001 // |------------------------|-----------------|
2002 //
2003 // As AtaBus is used to manage ATA devices, we have to use the lowest transfer
2004 // rate to calculate the possible maximum timeout value for each read/write
2005 // operation. The timout value is rounded up to nearest integar and here an
2006 // additional 30s is added to follow ATA spec in which it mentioned that the
2007 // device may take up to 30s to respond commands in the Standby/Idle mode.
2008 //
2009 // Calculate the maximum timeout value for PIO read/write operation.
2010 //
2011 Packet.Timeout = TIMER_PERIOD_SECONDS (
2012 DivU64x32 (
2013 MultU64x32 (TransferLength, DeviceData->Media.BlockSize),
2014 3300000
2015 ) + 31
2016 );
2017
2018 return AtaPassThru->PassThru (
2019 AtaPassThru,
2020 DeviceData->Port,
2021 DeviceData->PortMultiplier,
2022 &Packet
2023 );
2024}
2025
2064 IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData,
2065 IN OUT VOID *Buffer,
2066 IN UINT8 SecurityProtocolId,
2067 IN UINT16 SecurityProtocolSpecificData,
2068 IN UINTN TransferLength,
2069 IN BOOLEAN IsTrustSend,
2070 IN UINT64 Timeout,
2071 OUT UINTN *TransferLengthOut
2072 )
2073{
2075 EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru;
2078 EFI_STATUS Status;
2079 VOID *NewBuffer;
2080
2081 Private = DeviceData->Private;
2082 AtaPassThru = &Private->AtaPassThruPpi;
2083
2084 //
2085 // Ensure IsTrustSend are valid boolean values
2086 //
2087 ASSERT ((UINTN)IsTrustSend < 2);
2088 if ((UINTN)IsTrustSend >= 2) {
2089 return EFI_INVALID_PARAMETER;
2090 }
2091
2092 //
2093 // Prepare for ATA command block.
2094 //
2095 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
2096 if (TransferLength == 0) {
2097 Acb.AtaCommand = ATA_CMD_TRUST_NON_DATA;
2098 } else {
2099 Acb.AtaCommand = mAtaTrustCommands[IsTrustSend];
2100 }
2101
2102 Acb.AtaFeatures = SecurityProtocolId;
2103 Acb.AtaSectorCount = (UINT8)(TransferLength / 512);
2104 Acb.AtaSectorNumber = (UINT8)((TransferLength / 512) >> 8);
2105 //
2106 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
2107 // Here use big endian for Cylinder register.
2108 //
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)));
2114
2115 //
2116 // Prepare for ATA pass through packet.
2117 //
2118 ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
2119 if (TransferLength == 0) {
2120 Packet.InTransferLength = 0;
2121 Packet.OutTransferLength = 0;
2122 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
2123 } else if (IsTrustSend) {
2124 //
2125 // Check the alignment of the incoming buffer prior to invoking underlying
2126 // ATA PassThru PPI.
2127 //
2128 if ((AtaPassThru->Mode->IoAlign > 1) &&
2129 !ADDRESS_IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign))
2130 {
2131 NewBuffer = AllocateAlignedPages (
2132 EFI_SIZE_TO_PAGES (TransferLength),
2133 AtaPassThru->Mode->IoAlign
2134 );
2135 if (NewBuffer == NULL) {
2136 return EFI_OUT_OF_RESOURCES;
2137 }
2138
2139 CopyMem (NewBuffer, Buffer, TransferLength);
2140 Buffer = NewBuffer;
2141 }
2142
2143 Packet.OutDataBuffer = Buffer;
2144 Packet.OutTransferLength = (UINT32)TransferLength;
2145 Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2146 } else {
2147 Packet.InDataBuffer = Buffer;
2148 Packet.InTransferLength = (UINT32)TransferLength;
2149 Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2150 }
2151
2152 Packet.Asb = NULL;
2153 Packet.Acb = &Acb;
2154 Packet.Timeout = Timeout;
2155 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
2156
2157 Status = AtaPassThru->PassThru (
2158 AtaPassThru,
2159 DeviceData->Port,
2160 DeviceData->PortMultiplier,
2161 &Packet
2162 );
2163 if (TransferLengthOut != NULL) {
2164 if (!IsTrustSend) {
2165 *TransferLengthOut = Packet.InTransferLength;
2166 }
2167 }
2168
2169 return Status;
2170}
UINT64 UINTN
VOID AhciClearPortStatus(IN UINTN AhciBar, IN UINT8 Port)
Definition: AhciMode.c:302
UINT8 AhciGetNumberOfPortsFromMap(IN UINT32 PortBitMap)
Definition: AhciMode.c:1190
VOID AhciOrReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 OrData)
Definition: AhciMode.c:142
EFI_STATUS AhciModeInitialization(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private)
Definition: AhciMode.c:1664
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)
Definition: AhciMode.c:981
VOID AhciBuildCommandFis(IN OUT EFI_AHCI_COMMAND_FIS *CmdFis, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock)
Definition: AhciMode.c:529
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)
Definition: AhciMode.c:1602
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)
Definition: AhciMode.c:2063
EFI_STATUS AhciGetPortFromMap(IN UINT32 PortBitMap, IN UINT8 PortIndex, OUT UINT8 *Port)
Definition: AhciMode.c:1222
EFI_STATUS EFIAPI AhciWaitMmioSet(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 MaskValue, IN UINT32 TestValue, IN UINT64 Timeout)
Definition: AhciMode.c:172
VOID AhciAndReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 AndData)
Definition: AhciMode.c:119
EFI_LBA GetAtapi6Capacity(IN ATA_IDENTIFY_DATA *IdentifyData)
Definition: AhciMode.c:1415
EFI_STATUS AhciReset(IN UINTN AhciBar, IN UINT64 Timeout)
Definition: AhciMode.c:1084
VOID AhciWriteReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 Data)
Definition: AhciMode.c:101
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)
Definition: AhciMode.c:717
EFI_STATUS AhciCheckMemSet(IN UINTN Address, IN UINT32 MaskValue, IN UINT32 TestValue)
Definition: AhciMode.c:215
EFI_STATUS IdentifyAtaDevice(IN OUT PEI_AHCI_ATA_DEVICE_DATA *DeviceData)
Definition: AhciMode.c:1465
EFI_STATUS AhciCreateTransferDescriptor(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private)
Definition: AhciMode.c:1263
EFI_STATUS AhciDisableFisReceive(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
Definition: AhciMode.c:368
EFI_STATUS AhciIdentify(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN ATA_IDENTIFY_DATA *Buffer)
Definition: AhciMode.c:1143
EFI_STATUS AhciStopCommand(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
Definition: AhciMode.c:574
EFI_STATUS AhciStartCommand(IN UINTN AhciBar, IN UINT8 Port, IN UINT8 CommandSlot, IN UINT64 Timeout)
Definition: AhciMode.c:617
UINT32 AhciReadReg(IN UINTN AhciBar, IN UINT32 Offset)
Definition: AhciMode.c:79
EFI_STATUS AhciWaitMemSet(IN EFI_PHYSICAL_ADDRESS Address, IN UINT32 MaskValue, IN UINT32 TestValue, IN UINT64 Timeout)
Definition: AhciMode.c:246
EFI_STATUS TransferAtaDevice(IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, IN OUT VOID *Buffer, IN EFI_LBA StartLba, IN UINT32 TransferLength, IN BOOLEAN IsWrite)
Definition: AhciMode.c:1924
EFI_STATUS AhciEnableFisReceive(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
Definition: AhciMode.c:340
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)
Definition: AhciMode.c:422
EFI_STATUS IoMmuUnmap(IN VOID *Mapping)
Definition: DmaMem.c:132
EFI_STATUS IoMmuAllocateBuffer(IN UINTN Pages, OUT VOID **HostAddress, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
Definition: DmaMem.c:170
EFI_STATUS IoMmuMap(IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
Definition: DmaMem.c:60
EFI_STATUS IoMmuFreeBuffer(IN UINTN Pages, IN VOID *HostAddress, IN VOID *Mapping)
Definition: DmaMem.c:251
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
#define ATA_CMD_READ_SECTORS
defined from ATA-1
Definition: Atapi.h:544
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
Definition: Atapi.h:542
#define ATA_CMD_WRITE_SECTORS_EXT
defined from ATA-6
Definition: Atapi.h:563
#define ATA_CMD_READ_SECTORS_EXT
defined from ATA-6
Definition: Atapi.h:548
#define ATA_CMD_WRITE_SECTORS
defined from ATA-1
Definition: Atapi.h:558
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
Definition: HighBitSet32.c:27
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define MSG_SATA_DP
Definition: DevicePath.h:510
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
Definition: IoLib.c:262
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
Definition: IoLib.c:309
#define NULL
Definition: Base.h:319
#define ADDRESS_IS_ALIGNED(Address, Alignment)
Definition: Base.h:923
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT64 EFI_PEI_LBA
Definition: BlockIo.h:41
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
EDKII_IOMMU_OPERATION
Definition: IoMmu.h:44
@ EdkiiIoMmuOperationBusMasterWrite
Definition: IoMmu.h:54
@ EdkiiIoMmuOperationBusMasterRead
Definition: IoMmu.h:49
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
UINT64 EFI_LBA
Definition: UefiBaseType.h:45
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT16 config
General Configuration.
Definition: Atapi.h:79
UINT16 logic_sector_size_lo
word 117
Definition: Atapi.h:144
UINT16 phy_logic_sector_support
word 106
Definition: Atapi.h:139
UINT16 logic_sector_size_hi
word 118
Definition: Atapi.h:145
EFI_ATA_STATUS_BLOCK * Asb
Definition: AtaPassThru.h:114
EFI_ATA_PASS_THRU_LENGTH Length
Definition: AtaPassThru.h:167
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
Definition: AtaPassThru.h:163
EFI_ATA_COMMAND_BLOCK * Acb
Definition: AtaPassThru.h:119
EFI_PEI_LBA LastBlock
Definition: BlockIo2.h:64