1 /** @file
2   The AhciPei driver is used to manage ATA hard disk device working under AHCI
3   mode at PEI phase.
4 
5   Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
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 //
20 EFI_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 //
28 UINT8 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 //
42 UINT8  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 
59 UINT32 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 
69 
70 /**
71   Read AHCI Operation register.
72 
73   @param[in] AhciBar    AHCI bar address.
74   @param[in] Offset     The operation register offset.
75 
76   @return The register content read.
77 
78 **/
79 UINT32
AhciReadReg(IN UINTN AhciBar,IN UINT32 Offset)80 AhciReadReg (
81   IN UINTN     AhciBar,
82   IN UINT32    Offset
83   )
84 {
85   UINT32   Data;
86 
87   Data = 0;
88   Data = MmioRead32 (AhciBar + Offset);
89 
90   return Data;
91 }
92 
93 /**
94   Write AHCI Operation register.
95 
96   @param[in] AhciBar    AHCI bar address.
97   @param[in] Offset     The operation register offset.
98   @param[in] Data       The Data used to write down.
99 
100 **/
101 VOID
AhciWriteReg(IN UINTN AhciBar,IN UINT32 Offset,IN UINT32 Data)102 AhciWriteReg (
103   IN UINTN     AhciBar,
104   IN UINT32    Offset,
105   IN UINT32    Data
106   )
107 {
108   MmioWrite32 (AhciBar + Offset, Data);
109 }
110 
111 /**
112   Do AND operation with the value of AHCI Operation register.
113 
114   @param[in] AhciBar    AHCI bar address.
115   @param[in] Offset     The operation register offset.
116   @param[in] AndData    The data used to do AND operation.
117 
118 **/
119 VOID
AhciAndReg(IN UINTN AhciBar,IN UINT32 Offset,IN UINT32 AndData)120 AhciAndReg (
121   IN UINTN     AhciBar,
122   IN UINT32    Offset,
123   IN UINT32    AndData
124   )
125 {
126   UINT32 Data;
127 
128   Data  = AhciReadReg (AhciBar, Offset);
129   Data &= AndData;
130 
131   AhciWriteReg (AhciBar, Offset, Data);
132 }
133 
134 /**
135   Do OR operation with the Value of AHCI Operation register.
136 
137   @param[in] AhciBar    AHCI bar address.
138   @param[in] Offset     The operation register offset.
139   @param[in] OrData     The Data used to do OR operation.
140 
141 **/
142 VOID
AhciOrReg(IN UINTN AhciBar,IN UINT32 Offset,IN UINT32 OrData)143 AhciOrReg (
144   IN UINTN     AhciBar,
145   IN UINT32    Offset,
146   IN UINT32    OrData
147   )
148 {
149   UINT32 Data;
150 
151   Data  = AhciReadReg (AhciBar, Offset);
152   Data |= OrData;
153 
154   AhciWriteReg (AhciBar, Offset, Data);
155 }
156 
157 /**
158   Wait for memory set to the test Value.
159 
160   @param[in] AhciBar      AHCI bar address.
161   @param[in] Offset       The memory offset to test.
162   @param[in] MaskValue    The mask Value of memory.
163   @param[in] TestValue    The test Value of memory.
164   @param[in] Timeout      The timeout, in 100ns units, for wait memory set.
165 
166   @retval EFI_DEVICE_ERROR    The memory is not set.
167   @retval EFI_TIMEOUT         The memory setting is time out.
168   @retval EFI_SUCCESS         The memory is correct set.
169 
170 **/
171 EFI_STATUS
172 EFIAPI
AhciWaitMmioSet(IN UINTN AhciBar,IN UINT32 Offset,IN UINT32 MaskValue,IN UINT32 TestValue,IN UINT64 Timeout)173 AhciWaitMmioSet (
174   IN UINTN     AhciBar,
175   IN UINT32    Offset,
176   IN UINT32    MaskValue,
177   IN UINT32    TestValue,
178   IN UINT64    Timeout
179   )
180 {
181   UINT32    Value;
182   UINT32    Delay;
183 
184   Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
185 
186   do {
187     Value = AhciReadReg (AhciBar, Offset) & MaskValue;
188 
189     if (Value == TestValue) {
190       return EFI_SUCCESS;
191     }
192 
193     //
194     // Stall for 100 microseconds.
195     //
196     MicroSecondDelay (100);
197 
198     Delay--;
199 
200   } while (Delay > 0);
201 
202   return EFI_TIMEOUT;
203 }
204 
205 /**
206   Check the memory status to the test value.
207 
208   @param[in] Address       The memory address to test.
209   @param[in] MaskValue     The mask value of memory.
210   @param[in] TestValue     The test value of memory.
211 
212   @retval EFI_NOT_READY    The memory is not set.
213   @retval EFI_SUCCESS      The memory is correct set.
214 
215 **/
216 EFI_STATUS
AhciCheckMemSet(IN UINTN Address,IN UINT32 MaskValue,IN UINT32 TestValue)217 AhciCheckMemSet (
218   IN UINTN     Address,
219   IN UINT32    MaskValue,
220   IN UINT32    TestValue
221   )
222 {
223   UINT32     Value;
224 
225   Value  = *(volatile UINT32 *) Address;
226   Value &= MaskValue;
227 
228   if (Value == TestValue) {
229     return EFI_SUCCESS;
230   } else {
231     return EFI_NOT_READY;
232   }
233 }
234 
235 /**
236   Wait for the value of the specified system memory set to the test value.
237 
238   @param[in] Address      The system memory address to test.
239   @param[in] MaskValue    The mask value of memory.
240   @param[in] TestValue    The test value of memory.
241   @param[in] Timeout      The timeout, in 100ns units, for wait memory set.
242 
243   @retval EFI_TIMEOUT    The system memory setting is time out.
244   @retval EFI_SUCCESS    The system memory is correct set.
245 
246 **/
247 EFI_STATUS
AhciWaitMemSet(IN EFI_PHYSICAL_ADDRESS Address,IN UINT32 MaskValue,IN UINT32 TestValue,IN UINT64 Timeout)248 AhciWaitMemSet (
249   IN  EFI_PHYSICAL_ADDRESS    Address,
250   IN  UINT32                  MaskValue,
251   IN  UINT32                  TestValue,
252   IN  UINT64                  Timeout
253   )
254 {
255   UINT32     Value;
256   UINT64     Delay;
257   BOOLEAN    InfiniteWait;
258 
259   if (Timeout == 0) {
260     InfiniteWait = TRUE;
261   } else {
262     InfiniteWait = FALSE;
263   }
264 
265   Delay =  DivU64x32 (Timeout, 1000) + 1;
266 
267   do {
268     //
269     // Access system memory to see if the value is the tested one.
270     //
271     // The system memory pointed by Address will be updated by the
272     // SATA Host Controller, "volatile" is introduced to prevent
273     // compiler from optimizing the access to the memory address
274     // to only read once.
275     //
276     Value  = *(volatile UINT32 *) (UINTN) Address;
277     Value &= MaskValue;
278 
279     if (Value == TestValue) {
280       return EFI_SUCCESS;
281     }
282 
283     //
284     // Stall for 100 microseconds.
285     //
286     MicroSecondDelay (100);
287 
288     Delay--;
289 
290   } while (InfiniteWait || (Delay > 0));
291 
292   return EFI_TIMEOUT;
293 }
294 
295 /**
296 
297   Clear the port interrupt and error status. It will also clear HBA interrupt
298   status.
299 
300   @param[in] AhciBar    AHCI bar address.
301   @param[in] Port       The number of port.
302 
303 **/
304 VOID
AhciClearPortStatus(IN UINTN AhciBar,IN UINT8 Port)305 AhciClearPortStatus (
306   IN UINTN    AhciBar,
307   IN UINT8    Port
308   )
309 {
310   UINT32    Offset;
311 
312   //
313   // Clear any error status
314   //
315   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
316   AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
317 
318   //
319   // Clear any port interrupt status
320   //
321   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IS;
322   AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
323 
324   //
325   // Clear any HBA interrupt status
326   //
327   AhciWriteReg (AhciBar, AHCI_IS_OFFSET, AhciReadReg (AhciBar, AHCI_IS_OFFSET));
328 }
329 
330 /**
331   Enable the FIS running for giving port.
332 
333   @param[in] AhciBar    AHCI bar address.
334   @param[in] Port       The number of port.
335   @param[in] Timeout    The timeout, in 100ns units, to enabling FIS.
336 
337   @retval EFI_DEVICE_ERROR    The FIS enable setting fails.
338   @retval EFI_TIMEOUT         The FIS enable setting is time out.
339   @retval EFI_SUCCESS         The FIS enable successfully.
340 
341 **/
342 EFI_STATUS
AhciEnableFisReceive(IN UINTN AhciBar,IN UINT8 Port,IN UINT64 Timeout)343 AhciEnableFisReceive (
344   IN UINTN     AhciBar,
345   IN UINT8     Port,
346   IN UINT64    Timeout
347   )
348 {
349   UINT32 Offset;
350 
351   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
352   AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
353 
354   return EFI_SUCCESS;
355 }
356 
357 /**
358   Disable the FIS running for giving port.
359 
360   @param[in] AhciBar    AHCI bar address.
361   @param[in] Port       The number of port.
362   @param[in] Timeout    The timeout value of disabling FIS, uses 100ns as a unit.
363 
364   @retval EFI_DEVICE_ERROR    The FIS disable setting fails.
365   @retval EFI_TIMEOUT         The FIS disable setting is time out.
366   @retval EFI_UNSUPPORTED     The port is in running state.
367   @retval EFI_SUCCESS         The FIS disable successfully.
368 
369 **/
370 EFI_STATUS
AhciDisableFisReceive(IN UINTN AhciBar,IN UINT8 Port,IN UINT64 Timeout)371 AhciDisableFisReceive (
372   IN UINTN     AhciBar,
373   IN UINT8     Port,
374   IN UINT64    Timeout
375   )
376 {
377   UINT32    Offset;
378   UINT32    Data;
379 
380   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
381   Data   = AhciReadReg (AhciBar, Offset);
382 
383   //
384   // Before disabling Fis receive, the DMA engine of the port should NOT be in
385   // running status.
386   //
387   if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) != 0) {
388     return EFI_UNSUPPORTED;
389   }
390 
391   //
392   // Check if the Fis receive DMA engine for the port is running.
393   //
394   if ((Data & AHCI_PORT_CMD_FR) != AHCI_PORT_CMD_FR) {
395     return EFI_SUCCESS;
396   }
397 
398   AhciAndReg (AhciBar, Offset, (UINT32)~(AHCI_PORT_CMD_FRE));
399 
400   return AhciWaitMmioSet (
401            AhciBar,
402            Offset,
403            AHCI_PORT_CMD_FR,
404            0,
405            Timeout
406            );
407 }
408 
409 /**
410   Build the command list, command table and prepare the fis receiver.
411 
412   @param[in]     Private              The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
413   @param[in]     Port                 The number of port.
414   @param[in]     PortMultiplier       The number of port multiplier.
415   @param[in]     FisIndex             The offset index of the FIS base address.
416   @param[in]     CommandFis           The control fis will be used for the transfer.
417   @param[in]     CommandList          The command list will be used for the transfer.
418   @param[in]     CommandSlotNumber    The command slot will be used for the transfer.
419   @param[in,out] DataPhysicalAddr     The pointer to the data buffer pci bus master
420                                       address.
421   @param[in]     DataLength           The data count to be transferred.
422 
423 **/
424 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)425 AhciBuildCommand (
426   IN     PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private,
427   IN     UINT8                               Port,
428   IN     UINT8                               PortMultiplier,
429   IN     UINT8                               FisIndex,
430   IN     EFI_AHCI_COMMAND_FIS                *CommandFis,
431   IN     EFI_AHCI_COMMAND_LIST               *CommandList,
432   IN     UINT8                               CommandSlotNumber,
433   IN OUT VOID                                *DataPhysicalAddr,
434   IN     UINT32                              DataLength
435   )
436 {
437   EFI_AHCI_REGISTERS    *AhciRegisters;
438   UINTN                 AhciBar;
439   UINT64                BaseAddr;
440   UINT32                PrdtNumber;
441   UINT32                PrdtIndex;
442   UINTN                 RemainedData;
443   UINTN                 MemAddr;
444   DATA_64               Data64;
445   UINT32                Offset;
446 
447   AhciRegisters = &Private->AhciRegisters;
448   AhciBar       = Private->MmioBase;
449 
450   //
451   // Filling the PRDT
452   //
453   PrdtNumber = (UINT32)DivU64x32 (
454                          (UINT64)DataLength + AHCI_MAX_DATA_PER_PRDT - 1,
455                          AHCI_MAX_DATA_PER_PRDT
456                          );
457 
458   //
459   // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
460   // It also limits that the maximum amount of the PRDT entry in the command table
461   // is 65535.
462   // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
463   // PRDT entries.
464   //
465   ASSERT (PrdtNumber <= AHCI_MAX_PRDT_NUMBER);
466   if (PrdtNumber > AHCI_MAX_PRDT_NUMBER) {
467     return;
468   }
469 
470   Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
471 
472   BaseAddr = Data64.Uint64;
473 
474   ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
475 
476   ZeroMem (AhciRegisters->AhciCmdTable, sizeof (EFI_AHCI_COMMAND_TABLE));
477 
478   CommandFis->AhciCFisPmNum = PortMultiplier;
479 
480   CopyMem (&AhciRegisters->AhciCmdTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
481 
482   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
483   AhciAndReg (AhciBar, Offset, (UINT32)~(AHCI_PORT_CMD_DLAE | AHCI_PORT_CMD_ATAPI));
484 
485   RemainedData = (UINTN) DataLength;
486   MemAddr      = (UINTN) DataPhysicalAddr;
487   CommandList->AhciCmdPrdtl = PrdtNumber;
488 
489   for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
490     if (RemainedData < AHCI_MAX_DATA_PER_PRDT) {
491       AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
492     } else {
493       AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = AHCI_MAX_DATA_PER_PRDT - 1;
494     }
495 
496     Data64.Uint64 = (UINT64)MemAddr;
497     AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDba  = Data64.Uint32.Lower32;
498     AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
499     RemainedData -= AHCI_MAX_DATA_PER_PRDT;
500     MemAddr      += AHCI_MAX_DATA_PER_PRDT;
501   }
502 
503   //
504   // Set the last PRDT to Interrupt On Complete
505   //
506   if (PrdtNumber > 0) {
507     AhciRegisters->AhciCmdTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
508   }
509 
510   CopyMem (
511     (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
512     CommandList,
513     sizeof (EFI_AHCI_COMMAND_LIST)
514     );
515 
516   Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCmdTable;
517   AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba  = Data64.Uint32.Lower32;
518   AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
519   AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp   = PortMultiplier;
520 }
521 
522 /**
523   Build a command FIS.
524 
525   @param[in,out] CmdFis             A pointer to the EFI_AHCI_COMMAND_FIS data
526                                     structure.
527   @param[in]     AtaCommandBlock    A pointer to the EFI_ATA_COMMAND_BLOCK data
528                                     structure.
529 
530 **/
531 VOID
AhciBuildCommandFis(IN OUT EFI_AHCI_COMMAND_FIS * CmdFis,IN EFI_ATA_COMMAND_BLOCK * AtaCommandBlock)532 AhciBuildCommandFis (
533   IN OUT EFI_AHCI_COMMAND_FIS     *CmdFis,
534   IN     EFI_ATA_COMMAND_BLOCK    *AtaCommandBlock
535   )
536 {
537   ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
538 
539   CmdFis->AhciCFisType = AHCI_FIS_REGISTER_H2D;
540   //
541   // Indicator it's a command
542   //
543   CmdFis->AhciCFisCmdInd      = 0x1;
544   CmdFis->AhciCFisCmd         = AtaCommandBlock->AtaCommand;
545 
546   CmdFis->AhciCFisFeature     = AtaCommandBlock->AtaFeatures;
547   CmdFis->AhciCFisFeatureExp  = AtaCommandBlock->AtaFeaturesExp;
548 
549   CmdFis->AhciCFisSecNum      = AtaCommandBlock->AtaSectorNumber;
550   CmdFis->AhciCFisSecNumExp   = AtaCommandBlock->AtaSectorNumberExp;
551 
552   CmdFis->AhciCFisClyLow      = AtaCommandBlock->AtaCylinderLow;
553   CmdFis->AhciCFisClyLowExp   = AtaCommandBlock->AtaCylinderLowExp;
554 
555   CmdFis->AhciCFisClyHigh     = AtaCommandBlock->AtaCylinderHigh;
556   CmdFis->AhciCFisClyHighExp  = AtaCommandBlock->AtaCylinderHighExp;
557 
558   CmdFis->AhciCFisSecCount    = AtaCommandBlock->AtaSectorCount;
559   CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
560 
561   CmdFis->AhciCFisDevHead     = (UINT8) (AtaCommandBlock->AtaDeviceHead | 0xE0);
562 }
563 
564 /**
565   Stop command running for giving port
566 
567   @param[in] AhciBar    AHCI bar address.
568   @param[in] Port       The number of port.
569   @param[in] Timeout    The timeout value, in 100ns units, to stop.
570 
571   @retval EFI_DEVICE_ERROR    The command stop unsuccessfully.
572   @retval EFI_TIMEOUT         The operation is time out.
573   @retval EFI_SUCCESS         The command stop successfully.
574 
575 **/
576 EFI_STATUS
AhciStopCommand(IN UINTN AhciBar,IN UINT8 Port,IN UINT64 Timeout)577 AhciStopCommand (
578   IN  UINTN     AhciBar,
579   IN  UINT8     Port,
580   IN  UINT64    Timeout
581   )
582 {
583   UINT32    Offset;
584   UINT32    Data;
585 
586   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
587   Data   = AhciReadReg (AhciBar, Offset);
588 
589   if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) == 0) {
590     return EFI_SUCCESS;
591   }
592 
593   if ((Data & AHCI_PORT_CMD_ST) != 0) {
594     AhciAndReg (AhciBar, Offset, (UINT32)~(AHCI_PORT_CMD_ST));
595   }
596 
597   return AhciWaitMmioSet (
598            AhciBar,
599            Offset,
600            AHCI_PORT_CMD_CR,
601            0,
602            Timeout
603            );
604 }
605 
606 /**
607   Start command for give slot on specific port.
608 
609   @param[in] AhciBar       AHCI bar address.
610   @param[in] Port          The number of port.
611   @param[in] CommandSlot   The number of Command Slot.
612   @param[in] Timeout       The timeout value, in 100ns units, to start.
613 
614   @retval EFI_DEVICE_ERROR    The command start unsuccessfully.
615   @retval EFI_TIMEOUT         The operation is time out.
616   @retval EFI_SUCCESS         The command start successfully.
617 
618 **/
619 EFI_STATUS
AhciStartCommand(IN UINTN AhciBar,IN UINT8 Port,IN UINT8 CommandSlot,IN UINT64 Timeout)620 AhciStartCommand (
621   IN  UINTN     AhciBar,
622   IN  UINT8     Port,
623   IN  UINT8     CommandSlot,
624   IN  UINT64    Timeout
625   )
626 {
627   UINT32        CmdSlotBit;
628   EFI_STATUS    Status;
629   UINT32        PortStatus;
630   UINT32        StartCmd;
631   UINT32        PortTfd;
632   UINT32        Offset;
633   UINT32        Capability;
634 
635   //
636   // Collect AHCI controller information
637   //
638   Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
639 
640   CmdSlotBit = (UINT32) (1 << CommandSlot);
641 
642   AhciClearPortStatus (
643     AhciBar,
644     Port
645     );
646 
647   Status = AhciEnableFisReceive (
648              AhciBar,
649              Port,
650              Timeout
651              );
652   if (EFI_ERROR (Status)) {
653     return Status;
654   }
655 
656   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
657   PortStatus = AhciReadReg (AhciBar, Offset);
658 
659   StartCmd = 0;
660   if ((PortStatus & AHCI_PORT_CMD_ALPE) != 0) {
661     StartCmd = AhciReadReg (AhciBar, Offset);
662     StartCmd &= ~AHCI_PORT_CMD_ICC_MASK;
663     StartCmd |= AHCI_PORT_CMD_ACTIVE;
664   }
665 
666   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
667   PortTfd = AhciReadReg (AhciBar, Offset);
668 
669   if ((PortTfd & (AHCI_PORT_TFD_BSY | AHCI_PORT_TFD_DRQ)) != 0) {
670     if ((Capability & BIT24) != 0) {
671       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
672       AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_CLO);
673 
674       AhciWaitMmioSet (
675         AhciBar,
676         Offset,
677         AHCI_PORT_CMD_CLO,
678         0,
679         Timeout
680         );
681     }
682   }
683 
684   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
685   AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_ST | StartCmd);
686 
687   //
688   // Setting the command
689   //
690   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CI;
691   AhciAndReg (AhciBar, Offset, 0);
692   AhciOrReg  (AhciBar, Offset, CmdSlotBit);
693 
694   return EFI_SUCCESS;
695 }
696 
697 /**
698   Start a PIO Data transfer on specific port.
699 
700   @param[in]     Private            The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
701   @param[in]     Port               The number of port.
702   @param[in]     PortMultiplier     The number of port multiplier.
703   @param[in]     FisIndex           The offset index of the FIS base address.
704   @param[in]     Read               The transfer direction.
705   @param[in]     AtaCommandBlock    The EFI_ATA_COMMAND_BLOCK data.
706   @param[in,out] AtaStatusBlock     The EFI_ATA_STATUS_BLOCK data.
707   @param[in,out] MemoryAddr         The pointer to the data buffer.
708   @param[in]     DataCount          The data count to be transferred.
709   @param[in]     Timeout            The timeout value of PIO data transfer, uses
710                                     100ns as a unit.
711 
712   @retval EFI_DEVICE_ERROR        The PIO data transfer abort with error occurs.
713   @retval EFI_TIMEOUT             The operation is time out.
714   @retval EFI_UNSUPPORTED         The device is not ready for transfer.
715   @retval EFI_OUT_OF_RESOURCES    The operation fails due to lack of resources.
716   @retval EFI_SUCCESS             The PIO data transfer executes successfully.
717 
718 **/
719 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)720 AhciPioTransfer (
721   IN     PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private,
722   IN     UINT8                               Port,
723   IN     UINT8                               PortMultiplier,
724   IN     UINT8                               FisIndex,
725   IN     BOOLEAN                             Read,
726   IN     EFI_ATA_COMMAND_BLOCK               *AtaCommandBlock,
727   IN OUT EFI_ATA_STATUS_BLOCK                *AtaStatusBlock,
728   IN OUT VOID                                *MemoryAddr,
729   IN     UINT32                              DataCount,
730   IN     UINT64                              Timeout
731   )
732 {
733   EFI_STATUS                    Status;
734   EDKII_IOMMU_OPERATION         MapOp;
735   UINTN                         MapLength;
736   EFI_PHYSICAL_ADDRESS          PhyAddr;
737   VOID                          *MapData;
738   EFI_AHCI_REGISTERS            *AhciRegisters;
739   UINTN                         AhciBar;
740   BOOLEAN                       InfiniteWait;
741   UINT32                        Offset;
742   UINT32                        OldRfisLo;
743   UINT32                        OldRfisHi;
744   UINT32                        OldCmdListLo;
745   UINT32                        OldCmdListHi;
746   DATA_64                       Data64;
747   UINT32                        FisBaseAddr;
748   UINT32                        Delay;
749   EFI_AHCI_COMMAND_FIS          CFis;
750   EFI_AHCI_COMMAND_LIST         CmdList;
751   UINT32                        PortTfd;
752   UINT32                        PrdCount;
753   BOOLEAN                       PioFisReceived;
754   BOOLEAN                       D2hFisReceived;
755 
756   //
757   // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
758   // PRDT entries.
759   //
760   if (DataCount / (UINT32)AHCI_MAX_PRDT_NUMBER > AHCI_MAX_DATA_PER_PRDT) {
761     DEBUG ((
762       DEBUG_ERROR,
763       "%a: Driver only support a maximum of 0x%x PRDT entries, "
764       "current number of data byte 0x%x is too large, maximum allowed is 0x%x.\n",
765       __FUNCTION__, AHCI_MAX_PRDT_NUMBER, DataCount,
766       AHCI_MAX_PRDT_NUMBER * AHCI_MAX_DATA_PER_PRDT
767       ));
768     return EFI_UNSUPPORTED;
769   }
770 
771   MapOp     = Read ? EdkiiIoMmuOperationBusMasterWrite :
772                      EdkiiIoMmuOperationBusMasterRead;
773   MapLength = DataCount;
774   Status    = IoMmuMap (
775                 MapOp,
776                 MemoryAddr,
777                 &MapLength,
778                 &PhyAddr,
779                 &MapData
780                 );
781   if (EFI_ERROR (Status) || (MapLength != DataCount)) {
782     DEBUG ((DEBUG_ERROR, "%a: Fail to map data buffer.\n", __FUNCTION__));
783     return EFI_OUT_OF_RESOURCES;
784   }
785 
786   AhciRegisters  = &Private->AhciRegisters;
787   AhciBar        = Private->MmioBase;
788   InfiniteWait   = (Timeout == 0) ? TRUE : FALSE;
789 
790   //
791   // Fill FIS base address register
792   //
793   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
794   OldRfisLo     = AhciReadReg (AhciBar, Offset);
795   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
796   OldRfisHi     = AhciReadReg (AhciBar, Offset);
797   Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
798   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
799   AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
800   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
801   AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
802 
803   //
804   // Single task environment, we only use one command table for all port
805   //
806   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
807   OldCmdListLo  = AhciReadReg (AhciBar, Offset);
808   Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
809   OldCmdListHi  = AhciReadReg (AhciBar, Offset);
810   Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdList);
811   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
812   AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
813   Offset        = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
814   AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
815 
816   //
817   // Package read needed
818   //
819   AhciBuildCommandFis (&CFis, AtaCommandBlock);
820 
821   ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
822 
823   CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
824   CmdList.AhciCmdW   = Read ? 0 : 1;
825 
826   AhciBuildCommand (
827     Private,
828     Port,
829     PortMultiplier,
830     FisIndex,
831     &CFis,
832     &CmdList,
833     0,
834     (VOID *)(UINTN)PhyAddr,
835     DataCount
836     );
837 
838   Status = AhciStartCommand (
839              AhciBar,
840              Port,
841              0,
842              Timeout
843              );
844   if (EFI_ERROR (Status)) {
845     goto Exit;
846   }
847 
848   //
849   // Checking the status and wait the driver sending Data
850   //
851   FisBaseAddr = (UINT32)(UINTN)AhciRegisters->AhciRFis + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
852   if (Read) {
853     //
854     // Wait device sends the PIO setup fis before data transfer
855     //
856     Status = EFI_TIMEOUT;
857     Delay  = (UINT32) DivU64x32 (Timeout, 1000) + 1;
858     do {
859       PioFisReceived = FALSE;
860       D2hFisReceived = FALSE;
861       Offset = FisBaseAddr + AHCI_PIO_FIS_OFFSET;
862       Status = AhciCheckMemSet (Offset, AHCI_FIS_TYPE_MASK, AHCI_FIS_PIO_SETUP);
863       if (!EFI_ERROR (Status)) {
864         DEBUG ((DEBUG_INFO, "%a: PioFisReceived.\n", __FUNCTION__));
865         PioFisReceived = TRUE;
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", __FUNCTION__));
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", __FUNCTION__, 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 
932 Exit:
933   AhciStopCommand (
934     AhciBar,
935     Port,
936     Timeout
937     );
938 
939   AhciDisableFisReceive (
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 
962 /**
963   Start a non data transfer on specific port.
964 
965   @param[in]     Private            The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
966   @param[in]     Port               The number of port.
967   @param[in]     PortMultiplier     The number of port multiplier.
968   @param[in]     FisIndex           The offset index of the FIS base address.
969   @param[in]     AtaCommandBlock    The EFI_ATA_COMMAND_BLOCK data.
970   @param[in,out] AtaStatusBlock     The EFI_ATA_STATUS_BLOCK data.
971   @param[in]     Timeout            The timeout value of non data transfer, uses
972                                     100ns as a unit.
973 
974   @retval EFI_DEVICE_ERROR        The non data transfer abort with error occurs.
975   @retval EFI_TIMEOUT             The operation is time out.
976   @retval EFI_UNSUPPORTED         The device is not ready for transfer.
977   @retval EFI_SUCCESS             The non data transfer executes successfully.
978 
979 **/
980 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)981 AhciNonDataTransfer (
982   IN     PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private,
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;
997   EFI_AHCI_COMMAND_FIS        CFis;
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 
1012   AhciBuildCommand (
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 
1056 Exit:
1057   AhciStopCommand (
1058     AhciBar,
1059     Port,
1060     Timeout
1061     );
1062 
1063   AhciDisableFisReceive (
1064     AhciBar,
1065     Port,
1066     Timeout
1067     );
1068 
1069   return Status;
1070 }
1071 
1072 /**
1073   Do AHCI HBA reset.
1074 
1075   @param[in] AhciBar         AHCI bar address.
1076   @param[in] Timeout         The timeout, in 100ns units, to reset.
1077 
1078   @retval EFI_DEVICE_ERROR   AHCI controller is failed to complete hardware reset.
1079   @retval EFI_TIMEOUT        The reset operation is time out.
1080   @retval EFI_SUCCESS        AHCI controller is reset successfully.
1081 
1082 **/
1083 EFI_STATUS
AhciReset(IN UINTN AhciBar,IN UINT64 Timeout)1084 AhciReset (
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 
1126 /**
1127   Send Identify Drive command to a specific device.
1128 
1129   @param[in] Private           The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
1130   @param[in] Port              The number of port.
1131   @param[in] PortMultiplier    The port multiplier port number.
1132   @param[in] FisIndex          The offset index of the FIS base address.
1133   @param[in] Buffer            The data buffer to store IDENTIFY PACKET data.
1134 
1135   @retval EFI_SUCCESS              The cmd executes successfully.
1136   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
1137   @retval EFI_DEVICE_ERROR         The cmd abort with error occurs.
1138   @retval EFI_TIMEOUT              The operation is time out.
1139   @retval EFI_UNSUPPORTED          The device is not ready for executing.
1140 
1141 **/
1142 EFI_STATUS
AhciIdentify(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA * Private,IN UINT8 Port,IN UINT8 PortMultiplier,IN UINT8 FisIndex,IN ATA_IDENTIFY_DATA * Buffer)1143 AhciIdentify (
1144   IN PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private,
1145   IN UINT8                               Port,
1146   IN UINT8                               PortMultiplier,
1147   IN UINT8                               FisIndex,
1148   IN ATA_IDENTIFY_DATA                   *Buffer
1149   )
1150 {
1151   EFI_STATUS                     Status;
1152   EFI_ATA_COMMAND_BLOCK    Acb;
1153   EFI_ATA_STATUS_BLOCK     Asb;
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 
1181 
1182 /**
1183   Collect the number of bits set within a port bitmap.
1184 
1185   @param[in] PortBitMap    A 32-bit wide bit map of ATA AHCI ports.
1186 
1187   @retval The number of bits set in the bitmap.
1188 
1189 **/
1190 UINT8
AhciGetNumberOfPortsFromMap(IN UINT32 PortBitMap)1191 AhciGetNumberOfPortsFromMap (
1192   IN UINT32    PortBitMap
1193   )
1194 {
1195   UINT8    NumberOfPorts;
1196 
1197   NumberOfPorts = 0;
1198 
1199   while (PortBitMap != 0) {
1200     if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1201       NumberOfPorts++;
1202     }
1203     PortBitMap = PortBitMap >> 1;
1204   }
1205 
1206   return NumberOfPorts;
1207 }
1208 
1209 /**
1210   Get the specified port number from a port bitmap.
1211 
1212   @param[in]  PortBitMap    A 32-bit wide bit map of ATA AHCI ports.
1213   @param[in]  PortIndex     The specified port index.
1214   @param[out] Port          The port number of the port specified by PortIndex.
1215 
1216   @retval EFI_SUCCESS       The specified port is found and its port number is
1217                             in Port.
1218   @retval EFI_NOT_FOUND     Cannot find the specified port within the port bitmap.
1219 
1220 **/
1221 EFI_STATUS
AhciGetPortFromMap(IN UINT32 PortBitMap,IN UINT8 PortIndex,OUT UINT8 * Port)1222 AhciGetPortFromMap (
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     PortBitMap = PortBitMap >> 1;
1246     *Port      = *Port + 1;
1247   }
1248 
1249   return EFI_NOT_FOUND;
1250 }
1251 
1252 /**
1253   Allocate transfer-related data struct which is used at AHCI mode.
1254 
1255   @param[in,out] Private    A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA instance.
1256 
1257   @retval EFI_SUCCESS    Data structures are allocated successfully.
1258   @retval Others         Data structures are not allocated successfully.
1259 
1260 **/
1261 EFI_STATUS
AhciCreateTransferDescriptor(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA * Private)1262 AhciCreateTransferDescriptor (
1263   IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private
1264   )
1265 {
1266   EFI_STATUS              Status;
1267   UINTN                   AhciBar;
1268   EFI_AHCI_REGISTERS      *AhciRegisters;
1269   EFI_PHYSICAL_ADDRESS    DeviceAddress;
1270   VOID                    *Base;
1271   VOID                    *Mapping;
1272   UINT32                  Capability;
1273   UINT32                  PortImplementBitMap;
1274   UINT8                   MaxPortNumber;
1275   UINT8                   MaxCommandSlotNumber;
1276   UINTN                   MaxRFisSize;
1277   UINTN                   MaxCmdListSize;
1278   UINTN                   MaxCmdTableSize;
1279 
1280   AhciBar       = Private->MmioBase;
1281   AhciRegisters = &Private->AhciRegisters;
1282 
1283   //
1284   // Collect AHCI controller information
1285   //
1286   Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1287 
1288   //
1289   // Get the number of command slots per port supported by this HBA.
1290   //
1291   MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1);
1292   ASSERT (MaxCommandSlotNumber > 0);
1293   if (MaxCommandSlotNumber == 0) {
1294     return EFI_DEVICE_ERROR;
1295   }
1296 
1297   //
1298   // Get the highest bit of implemented ports which decides how many bytes are
1299   // allocated for recived FIS.
1300   //
1301   PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1302   MaxPortNumber       = (UINT8)(UINTN)(HighBitSet32(PortImplementBitMap) + 1);
1303   if (MaxPortNumber == 0) {
1304     return EFI_DEVICE_ERROR;
1305   }
1306   //
1307   // Get the number of ports that actually needed to be initialized.
1308   //
1309   MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1310 
1311   //
1312   // Allocate memory for received FIS.
1313   //
1314   MaxRFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
1315   Status = IoMmuAllocateBuffer (
1316              EFI_SIZE_TO_PAGES (MaxRFisSize),
1317              &Base,
1318              &DeviceAddress,
1319              &Mapping
1320              );
1321   if (EFI_ERROR (Status)) {
1322     return EFI_OUT_OF_RESOURCES;
1323   }
1324   ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
1325   AhciRegisters->AhciRFis    = Base;
1326   AhciRegisters->AhciRFisMap = Mapping;
1327   AhciRegisters->MaxRFisSize = MaxRFisSize;
1328   ZeroMem (AhciRegisters->AhciRFis, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxRFisSize));
1329 
1330   //
1331   // Allocate memory for command list.
1332   // Note that the implemenation is a single task model which only use a command
1333   // list for each port.
1334   //
1335   MaxCmdListSize = 1 * sizeof (EFI_AHCI_COMMAND_LIST);
1336   Status = IoMmuAllocateBuffer (
1337              EFI_SIZE_TO_PAGES (MaxCmdListSize),
1338              &Base,
1339              &DeviceAddress,
1340              &Mapping
1341              );
1342   if (EFI_ERROR (Status)) {
1343     Status = EFI_OUT_OF_RESOURCES;
1344     goto ErrorExit;
1345   }
1346   ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
1347   AhciRegisters->AhciCmdList    = Base;
1348   AhciRegisters->AhciCmdListMap = Mapping;
1349   AhciRegisters->MaxCmdListSize = MaxCmdListSize;
1350   ZeroMem (AhciRegisters->AhciCmdList, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdListSize));
1351 
1352   //
1353   // Allocate memory for command table
1354   // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
1355   //
1356   MaxCmdTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
1357   Status = IoMmuAllocateBuffer (
1358              EFI_SIZE_TO_PAGES (MaxCmdTableSize),
1359              &Base,
1360              &DeviceAddress,
1361              &Mapping
1362              );
1363   if (EFI_ERROR (Status)) {
1364     Status = EFI_OUT_OF_RESOURCES;
1365     goto ErrorExit;
1366   }
1367   ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS) (UINTN) Base));
1368   AhciRegisters->AhciCmdTable    = Base;
1369   AhciRegisters->AhciCmdTableMap = Mapping;
1370   AhciRegisters->MaxCmdTableSize = MaxCmdTableSize;
1371   ZeroMem (AhciRegisters->AhciCmdTable, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdTableSize));
1372 
1373   return EFI_SUCCESS;
1374 
1375 ErrorExit:
1376   if (AhciRegisters->AhciRFisMap != NULL) {
1377     IoMmuFreeBuffer (
1378        EFI_SIZE_TO_PAGES (AhciRegisters->MaxRFisSize),
1379        AhciRegisters->AhciRFis,
1380        AhciRegisters->AhciRFisMap
1381        );
1382     AhciRegisters->AhciRFis = NULL;
1383   }
1384 
1385   if (AhciRegisters->AhciCmdListMap != NULL) {
1386     IoMmuFreeBuffer (
1387        EFI_SIZE_TO_PAGES (AhciRegisters->MaxCmdListSize),
1388        AhciRegisters->AhciCmdList,
1389        AhciRegisters->AhciCmdListMap
1390        );
1391     AhciRegisters->AhciCmdList = NULL;
1392   }
1393 
1394   return Status;
1395 }
1396 
1397 /**
1398   Gets ATA device Capacity according to ATA 6.
1399 
1400   This function returns the capacity of the ATA device if it follows
1401   ATA 6 to support 48 bit addressing.
1402 
1403   @param[in] IdentifyData    A pointer to ATA_IDENTIFY_DATA structure.
1404 
1405   @return The capacity of the ATA device or 0 if the device does not support
1406           48-bit addressing defined in ATA 6.
1407 
1408 **/
1409 EFI_LBA
GetAtapi6Capacity(IN ATA_IDENTIFY_DATA * IdentifyData)1410 GetAtapi6Capacity (
1411   IN ATA_IDENTIFY_DATA    *IdentifyData
1412   )
1413 {
1414   EFI_LBA                       Capacity;
1415   EFI_LBA                       TmpLba;
1416   UINTN                         Index;
1417 
1418   if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
1419     //
1420     // The device doesn't support 48 bit addressing
1421     //
1422     return 0;
1423   }
1424 
1425   //
1426   // 48 bit address feature set is supported, get maximum capacity
1427   //
1428   Capacity = 0;
1429   for (Index = 0; Index < 4; Index++) {
1430     //
1431     // Lower byte goes first: word[100] is the lowest word, word[103] is highest
1432     //
1433     TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
1434     Capacity |= LShiftU64 (TmpLba, 16 * Index);
1435   }
1436 
1437   return Capacity;
1438 }
1439 
1440 /**
1441   Identifies ATA device via the Identify data.
1442 
1443   This function identifies the ATA device and initializes the media information.
1444 
1445   @attention This is boundary function that may receive untrusted input.
1446   @attention The input is from peripheral hardware device.
1447 
1448   The Identify Drive command response data from an ATA device is the peripheral
1449   hardware input, so this routine will do basic validation for the Identify Drive
1450   command response data.
1451 
1452   @param[in,out] DeviceData    A pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
1453 
1454   @retval EFI_SUCCESS        The device is successfully identified and media
1455                              information is correctly initialized.
1456   @retval EFI_UNSUPPORTED    The device is not a valid ATA device (hard disk).
1457 
1458 **/
1459 EFI_STATUS
IdentifyAtaDevice(IN OUT PEI_AHCI_ATA_DEVICE_DATA * DeviceData)1460 IdentifyAtaDevice (
1461   IN OUT PEI_AHCI_ATA_DEVICE_DATA    *DeviceData
1462   )
1463 {
1464   ATA_IDENTIFY_DATA          *IdentifyData;
1465   EFI_PEI_BLOCK_IO2_MEDIA    *Media;
1466   EFI_LBA                    Capacity;
1467   UINT32                     MaxSectorCount;
1468   UINT16                     PhyLogicSectorSupport;
1469 
1470   IdentifyData = DeviceData->IdentifyData;
1471   Media        = &DeviceData->Media;
1472 
1473   if ((IdentifyData->config & BIT15) != 0) {
1474     DEBUG ((
1475       DEBUG_ERROR, "%a: Not a hard disk device on Port 0x%x PortMultiplierPort 0x%x\n",
1476       __FUNCTION__, DeviceData->Port, DeviceData->PortMultiplier
1477       ));
1478     return EFI_UNSUPPORTED;
1479   }
1480 
1481   DEBUG ((
1482     DEBUG_INFO, "%a: Identify Device: Port 0x%x PortMultiplierPort 0x%x\n",
1483     __FUNCTION__, DeviceData->Port, DeviceData->PortMultiplier
1484     ));
1485 
1486   //
1487   // Skip checking whether the WORD 88 (supported UltraDMA by drive), since the
1488   // driver only support PIO data transfer for now.
1489   //
1490 
1491   //
1492   // Get the capacity information of the device.
1493   //
1494   Capacity = GetAtapi6Capacity (IdentifyData);
1495   if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
1496     //
1497     // Capacity exceeds 120GB. 48-bit addressing is really needed
1498     //
1499     DeviceData->Lba48Bit = TRUE;
1500   } else {
1501     //
1502     // This is a hard disk <= 120GB capacity, treat it as normal hard disk
1503     //
1504     Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) |
1505                         IdentifyData->user_addressable_sectors_lo;
1506     DeviceData->Lba48Bit = FALSE;
1507   }
1508 
1509   if (Capacity == 0) {
1510     DEBUG ((DEBUG_ERROR, "%a: Invalid Capacity (0) for ATA device.\n", __FUNCTION__));
1511     return EFI_UNSUPPORTED;
1512   }
1513   Media->LastBlock = (EFI_PEI_LBA) (Capacity - 1);
1514 
1515   Media->BlockSize = 0x200;
1516   //
1517   // Check whether Long Physical Sector Feature is supported
1518   //
1519   PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
1520   DEBUG ((
1521     DEBUG_INFO, "%a: PhyLogicSectorSupport = 0x%x\n",
1522     __FUNCTION__, PhyLogicSectorSupport
1523     ));
1524   if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
1525     //
1526     // Check logical block size
1527     //
1528     if ((PhyLogicSectorSupport & BIT12) != 0) {
1529       Media->BlockSize = (UINT32) (((IdentifyData->logic_sector_size_hi << 16) |
1530                                      IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
1531     }
1532   }
1533 
1534   //
1535   // Check BlockSize validity
1536   //
1537   MaxSectorCount = mMaxTransferBlockNumber[DeviceData->Lba48Bit];
1538   if ((Media->BlockSize == 0) || (Media->BlockSize > MAX_UINT32 / MaxSectorCount)) {
1539     DEBUG ((DEBUG_ERROR, "%a: Invalid BlockSize (0x%x).\n", __FUNCTION__, Media->BlockSize));
1540     return EFI_UNSUPPORTED;
1541   }
1542 
1543   DEBUG ((
1544     DEBUG_INFO, "%a: BlockSize = 0x%x, LastBlock = 0x%lx\n",
1545     __FUNCTION__, Media->BlockSize, Media->LastBlock
1546     ));
1547 
1548   if ((IdentifyData->trusted_computing_support & BIT0) != 0) {
1549     DEBUG ((DEBUG_INFO, "%a: Found Trust Computing feature support.\n", __FUNCTION__));
1550     DeviceData->TrustComputing = TRUE;
1551   }
1552 
1553   Media->InterfaceType  = MSG_SATA_DP;
1554   Media->RemovableMedia = FALSE;
1555   Media->MediaPresent   = TRUE;
1556   Media->ReadOnly       = FALSE;
1557 
1558   return EFI_SUCCESS;
1559 }
1560 
1561 /**
1562   Allocate device information data structure to contain device information.
1563   And insert the data structure to the tail of device list for tracing.
1564 
1565   @param[in,out] Private               A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA
1566                                        instance.
1567   @param[in]     DeviceIndex           The device index.
1568   @param[in]     Port                  The port number of the ATA device to send
1569                                        the command.
1570   @param[in]     PortMultiplierPort    The port multiplier port number of the ATA
1571                                        device to send the command.
1572                                        If there is no port multiplier, then specify
1573                                        0xFFFF.
1574   @param[in]     FisIndex              The index of the FIS of the ATA device to
1575                                        send the command.
1576   @param[in]     IdentifyData          The data buffer to store the output of the
1577                                        IDENTIFY command.
1578 
1579   @retval EFI_SUCCESS                  Successfully insert the ATA device to the
1580                                        tail of device list.
1581   @retval EFI_OUT_OF_RESOURCES         Not enough resource.
1582 
1583 **/
1584 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)1585 CreateNewDevice (
1586   IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private,
1587   IN     UINTN                               DeviceIndex,
1588   IN     UINT16                              Port,
1589   IN     UINT16                              PortMultiplier,
1590   IN     UINT8                               FisIndex,
1591   IN     ATA_IDENTIFY_DATA                   *IdentifyData
1592   )
1593 {
1594   PEI_AHCI_ATA_DEVICE_DATA    *DeviceData;
1595   EFI_STATUS                  Status;
1596 
1597   DeviceData = AllocateZeroPool (sizeof (PEI_AHCI_ATA_DEVICE_DATA));
1598   if (DeviceData == NULL) {
1599     return EFI_OUT_OF_RESOURCES;
1600   }
1601 
1602   if (IdentifyData != NULL) {
1603     DeviceData->IdentifyData = AllocateCopyPool (sizeof (ATA_IDENTIFY_DATA), IdentifyData);
1604     if (DeviceData->IdentifyData == NULL) {
1605       return EFI_OUT_OF_RESOURCES;
1606     }
1607   }
1608 
1609   DeviceData->Signature      = AHCI_PEI_ATA_DEVICE_DATA_SIGNATURE;
1610   DeviceData->Port           = Port;
1611   DeviceData->PortMultiplier = PortMultiplier;
1612   DeviceData->FisIndex       = FisIndex;
1613   DeviceData->DeviceIndex    = DeviceIndex;
1614   DeviceData->Private        = Private;
1615 
1616   Status = IdentifyAtaDevice (DeviceData);
1617   if (EFI_ERROR (Status)) {
1618     return Status;
1619   }
1620 
1621   if (DeviceData->TrustComputing) {
1622     Private->TrustComputingDevices++;
1623     DeviceData->TrustComputingDeviceIndex = Private->TrustComputingDevices;
1624   }
1625   Private->ActiveDevices++;
1626   InsertTailList (&Private->DeviceList, &DeviceData->Link);
1627 
1628   return EFI_SUCCESS;
1629 }
1630 
1631 /**
1632   Initialize ATA host controller at AHCI mode.
1633 
1634   The function is designed to initialize ATA host controller.
1635 
1636   @param[in,out] Private    A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA instance.
1637 
1638   @retval EFI_SUCCESS             The ATA AHCI controller is initialized successfully.
1639   @retval EFI_OUT_OF_RESOURCES    Not enough resource to complete while initializing
1640                                   the controller.
1641   @retval Others                  A device error occurred while initializing the
1642                                   controller.
1643 
1644 **/
1645 EFI_STATUS
AhciModeInitialization(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA * Private)1646 AhciModeInitialization (
1647   IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private
1648   )
1649 {
1650   EFI_STATUS            Status;
1651   UINTN                 AhciBar;
1652   UINT32                Capability;
1653   UINT32                Value;
1654   UINT8                 MaxPortNumber;
1655   UINT32                PortImplementBitMap;
1656   UINT32                PortInitializeBitMap;
1657   EFI_AHCI_REGISTERS    *AhciRegisters;
1658   UINT8                 PortIndex;
1659   UINT8                 Port;
1660   DATA_64               Data64;
1661   UINT32                Data;
1662   UINT32                Offset;
1663   UINT32                PhyDetectDelay;
1664   UINTN                 DeviceIndex;
1665   ATA_IDENTIFY_DATA     IdentifyData;
1666 
1667   AhciBar = Private->MmioBase;
1668 
1669   Status = AhciReset (AhciBar, AHCI_PEI_RESET_TIMEOUT);
1670   if (EFI_ERROR (Status)) {
1671     DEBUG ((DEBUG_ERROR, "%a: AHCI HBA reset failed with %r.\n", __FUNCTION__, Status));
1672     return EFI_DEVICE_ERROR;
1673   }
1674 
1675   //
1676   // Collect AHCI controller information
1677   //
1678   Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1679 
1680   //
1681   // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1682   //
1683   Value = AhciReadReg (AhciBar, AHCI_GHC_OFFSET);
1684   if ((Value & AHCI_GHC_ENABLE) == 0) {
1685     AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1686   }
1687 
1688   Status = AhciCreateTransferDescriptor (Private);
1689   if (EFI_ERROR (Status)) {
1690     DEBUG ((
1691       DEBUG_ERROR,
1692       "%a: Transfer-related data allocation failed with %r.\n",
1693       __FUNCTION__, Status
1694       ));
1695     return EFI_OUT_OF_RESOURCES;
1696   }
1697 
1698   //
1699   // Get the number of command slots per port supported by this HBA.
1700   //
1701   MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1);
1702 
1703   //
1704   // Get the bit map of those ports exposed by this HBA.
1705   // It indicates which ports that the HBA supports are available for software
1706   // to use.
1707   //
1708   PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1709 
1710   //
1711   // Get the number of ports that actually needed to be initialized.
1712   //
1713   MaxPortNumber = MIN (MaxPortNumber, (UINT8)(UINTN)(HighBitSet32(PortImplementBitMap) + 1));
1714   MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1715 
1716   PortInitializeBitMap = Private->PortBitMap & PortImplementBitMap;
1717   AhciRegisters        = &Private->AhciRegisters;
1718   DeviceIndex          = 0;
1719   //
1720   // Enumerate ATA ports
1721   //
1722   for (PortIndex = 1; PortIndex <= MaxPortNumber; PortIndex ++) {
1723     Status = AhciGetPortFromMap (PortInitializeBitMap, PortIndex, &Port);
1724     if (EFI_ERROR (Status)) {
1725       //
1726       // No more available port, just break out of the loop.
1727       //
1728       break;
1729     }
1730 
1731     if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
1732       //
1733       // Initialize FIS Base Address Register and Command List Base Address
1734       // Register for use.
1735       //
1736       Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) +
1737                       sizeof (EFI_AHCI_RECEIVED_FIS) * (PortIndex - 1);
1738       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
1739       AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1740       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
1741       AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1742 
1743       Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdList);
1744       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
1745       AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1746       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
1747       AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1748 
1749       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1750       Data = AhciReadReg (AhciBar, Offset);
1751       if ((Data & AHCI_PORT_CMD_CPD) != 0) {
1752         AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_POD);
1753       }
1754 
1755       if ((Capability & AHCI_CAP_SSS) != 0) {
1756         AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_SUD);
1757       }
1758 
1759       //
1760       // Disable aggressive power management.
1761       //
1762       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SCTL;
1763       AhciOrReg (AhciBar, Offset, AHCI_PORT_SCTL_IPM_INIT);
1764       //
1765       // Disable the reporting of the corresponding interrupt to system software.
1766       //
1767       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IE;
1768       AhciAndReg (AhciBar, Offset, 0);
1769 
1770       //
1771       // Enable FIS Receive DMA engine for the first D2H FIS.
1772       //
1773       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1774       AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
1775 
1776       //
1777       // Wait no longer than 15 ms to wait the Phy to detect the presence of a device.
1778       //
1779       PhyDetectDelay = AHCI_BUS_PHY_DETECT_TIMEOUT;
1780       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SSTS;
1781       do {
1782         Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_SSTS_DET_MASK;
1783         if ((Data == AHCI_PORT_SSTS_DET_PCE) || (Data == AHCI_PORT_SSTS_DET)) {
1784           break;
1785         }
1786 
1787         MicroSecondDelay (1000);
1788         PhyDetectDelay--;
1789       } while (PhyDetectDelay > 0);
1790 
1791       if (PhyDetectDelay == 0) {
1792         //
1793         // No device detected at this port.
1794         // Clear PxCMD.SUD for those ports at which there are no device present.
1795         //
1796         Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1797         AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_SUD));
1798         DEBUG ((DEBUG_ERROR, "%a: No device detected at Port %d.\n", __FUNCTION__, Port));
1799         continue;
1800       }
1801 
1802       //
1803       // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
1804       // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
1805       //
1806       PhyDetectDelay = 16 * 1000;
1807       do {
1808         Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
1809         if (AhciReadReg(AhciBar, Offset) != 0) {
1810           AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
1811         }
1812         Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1813 
1814         Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_TFD_MASK;
1815         if (Data == 0) {
1816           break;
1817         }
1818 
1819         MicroSecondDelay (1000);
1820         PhyDetectDelay--;
1821       } while (PhyDetectDelay > 0);
1822 
1823       if (PhyDetectDelay == 0) {
1824         DEBUG ((
1825           DEBUG_ERROR,
1826           "%a: Port %d device presence detected but phy not ready (TFD=0x%x).\n",
1827           __FUNCTION__, Port, Data
1828           ));
1829         continue;
1830       }
1831 
1832       //
1833       // When the first D2H register FIS is received, the content of PxSIG register is updated.
1834       //
1835       Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SIG;
1836       Status = AhciWaitMmioSet (
1837                  AhciBar,
1838                  Offset,
1839                  0x0000FFFF,
1840                  0x00000101,
1841                  160000000
1842                  );
1843       if (EFI_ERROR (Status)) {
1844         DEBUG ((
1845           DEBUG_ERROR,
1846           "%a: Error occurred when waiting for the first D2H register FIS - %r\n",
1847           __FUNCTION__, Status
1848           ));
1849         continue;
1850       }
1851 
1852       Data = AhciReadReg (AhciBar, Offset);
1853       if ((Data & AHCI_ATAPI_SIG_MASK) == AHCI_ATA_DEVICE_SIG) {
1854         Status = AhciIdentify (Private, Port, 0, PortIndex - 1, &IdentifyData);
1855         if (EFI_ERROR (Status)) {
1856           DEBUG ((DEBUG_ERROR, "%a: AhciIdentify() failed with %r\n", __FUNCTION__, Status));
1857           continue;
1858         }
1859         DEBUG ((DEBUG_INFO, "%a: ATA hard disk found on Port %d.\n", __FUNCTION__, Port));
1860       } else {
1861         continue;
1862       }
1863 
1864       //
1865       // Found an ATA hard disk device, add it into the device list.
1866       //
1867       DeviceIndex++;
1868       CreateNewDevice (
1869         Private,
1870         DeviceIndex,
1871         Port,
1872         0xFFFF,
1873         PortIndex - 1,
1874         &IdentifyData
1875         );
1876     }
1877   }
1878 
1879   return EFI_SUCCESS;
1880 }
1881 
1882 /**
1883   Transfer data from ATA device.
1884 
1885   This function performs one ATA pass through transaction to transfer data from/to
1886   ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
1887   interface of ATA pass through.
1888 
1889   @param[in]     DeviceData        A pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
1890   @param[in,out] Buffer            The pointer to the current transaction buffer.
1891   @param[in]     StartLba          The starting logical block address to be accessed.
1892   @param[in]     TransferLength    The block number or sector count of the transfer.
1893   @param[in]     IsWrite           Indicates whether it is a write operation.
1894 
1895   @retval EFI_SUCCESS    The data transfer is complete successfully.
1896   @return others         Some error occurs when transferring data.
1897 
1898 **/
1899 EFI_STATUS
TransferAtaDevice(IN PEI_AHCI_ATA_DEVICE_DATA * DeviceData,IN OUT VOID * Buffer,IN EFI_LBA StartLba,IN UINT32 TransferLength,IN BOOLEAN IsWrite)1900 TransferAtaDevice (
1901   IN     PEI_AHCI_ATA_DEVICE_DATA    *DeviceData,
1902   IN OUT VOID                        *Buffer,
1903   IN     EFI_LBA                     StartLba,
1904   IN     UINT32                      TransferLength,
1905   IN     BOOLEAN                     IsWrite
1906   )
1907 {
1908   PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private;
1909   EDKII_PEI_ATA_PASS_THRU_PPI         *AtaPassThru;
1910   EFI_ATA_COMMAND_BLOCK               Acb;
1911   EFI_ATA_PASS_THRU_COMMAND_PACKET    Packet;
1912 
1913   Private     = DeviceData->Private;
1914   AtaPassThru = &Private->AtaPassThruPpi;
1915 
1916   //
1917   // Ensure Lba48Bit and IsWrite are valid boolean values
1918   //
1919   ASSERT ((UINTN) DeviceData->Lba48Bit < 2);
1920   ASSERT ((UINTN) IsWrite < 2);
1921   if (((UINTN) DeviceData->Lba48Bit >= 2) ||
1922       ((UINTN) IsWrite >= 2)) {
1923     return EFI_INVALID_PARAMETER;
1924   }
1925 
1926   //
1927   // Prepare for ATA command block.
1928   //
1929   ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
1930   Acb.AtaCommand = mAtaCommands[DeviceData->Lba48Bit][IsWrite];
1931   Acb.AtaSectorNumber = (UINT8) StartLba;
1932   Acb.AtaCylinderLow  = (UINT8) RShiftU64 (StartLba, 8);
1933   Acb.AtaCylinderHigh = (UINT8) RShiftU64 (StartLba, 16);
1934   Acb.AtaDeviceHead   = (UINT8) (BIT7 | BIT6 | BIT5 |
1935                                  (DeviceData->PortMultiplier == 0xFFFF ?
1936                                  0 : (DeviceData->PortMultiplier << 4)));
1937   Acb.AtaSectorCount  = (UINT8) TransferLength;
1938   if (DeviceData->Lba48Bit) {
1939     Acb.AtaSectorNumberExp = (UINT8) RShiftU64 (StartLba, 24);
1940     Acb.AtaCylinderLowExp  = (UINT8) RShiftU64 (StartLba, 32);
1941     Acb.AtaCylinderHighExp = (UINT8) RShiftU64 (StartLba, 40);
1942     Acb.AtaSectorCountExp  = (UINT8) (TransferLength >> 8);
1943   } else {
1944     Acb.AtaDeviceHead      = (UINT8) (Acb.AtaDeviceHead | RShiftU64 (StartLba, 24));
1945   }
1946 
1947   //
1948   // Prepare for ATA pass through packet.
1949   //
1950   ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
1951   if (IsWrite) {
1952     Packet.OutDataBuffer     = Buffer;
1953     Packet.OutTransferLength = TransferLength;
1954   } else {
1955     Packet.InDataBuffer      = Buffer;
1956     Packet.InTransferLength  = TransferLength;
1957   }
1958   Packet.Asb      = NULL;
1959   Packet.Acb      = &Acb;
1960   Packet.Protocol = mAtaPassThruCmdProtocols[IsWrite];
1961   Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
1962   //
1963   // |------------------------|-----------------|
1964   // | ATA PIO Transfer Mode  |  Transfer Rate  |
1965   // |------------------------|-----------------|
1966   // |       PIO Mode 0       |  3.3Mbytes/sec  |
1967   // |------------------------|-----------------|
1968   // |       PIO Mode 1       |  5.2Mbytes/sec  |
1969   // |------------------------|-----------------|
1970   // |       PIO Mode 2       |  8.3Mbytes/sec  |
1971   // |------------------------|-----------------|
1972   // |       PIO Mode 3       | 11.1Mbytes/sec  |
1973   // |------------------------|-----------------|
1974   // |       PIO Mode 4       | 16.6Mbytes/sec  |
1975   // |------------------------|-----------------|
1976   //
1977   // As AtaBus is used to manage ATA devices, we have to use the lowest transfer
1978   // rate to calculate the possible maximum timeout value for each read/write
1979   // operation. The timout value is rounded up to nearest integar and here an
1980   // additional 30s is added to follow ATA spec in which it mentioned that the
1981   // device may take up to 30s to respond commands in the Standby/Idle mode.
1982   //
1983   // Calculate the maximum timeout value for PIO read/write operation.
1984   //
1985   Packet.Timeout = TIMER_PERIOD_SECONDS (
1986                      DivU64x32 (
1987                        MultU64x32 (TransferLength, DeviceData->Media.BlockSize),
1988                        3300000
1989                        ) + 31
1990                      );
1991 
1992   return AtaPassThru->PassThru (
1993                         AtaPassThru,
1994                         DeviceData->Port,
1995                         DeviceData->PortMultiplier,
1996                         &Packet
1997                         );
1998 }
1999 
2000 /**
2001   Trust transfer data from/to ATA device.
2002 
2003   This function performs one ATA pass through transaction to do a trust transfer
2004   from/to ATA device. It chooses the appropriate ATA command and protocol to invoke
2005   PassThru interface of ATA pass through.
2006 
2007   @param[in]     DeviceData     Pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
2008   @param[in,out] Buffer         The pointer to the current transaction buffer.
2009   @param[in]     SecurityProtocolId
2010                                 The value of the "Security Protocol" parameter
2011                                 of the security protocol command to be sent.
2012   @param[in]     SecurityProtocolSpecificData
2013                                 The value of the "Security Protocol Specific"
2014                                 parameter of the security protocol command to
2015                                 be sent.
2016   @param[in]     TransferLength The block number or sector count of the transfer.
2017   @param[in]     IsTrustSend    Indicates whether it is a trust send operation
2018                                 or not.
2019   @param[in]     Timeout        The timeout, in 100ns units, to use for the execution
2020                                 of the security protocol command. A Timeout value
2021                                 of 0 means that this function will wait indefinitely
2022                                 for the security protocol command to execute. If
2023                                 Timeout is greater than zero, then this function
2024                                 will return EFI_TIMEOUT if the time required to
2025                                 execute the receive data command is greater than
2026                                 Timeout.
2027   @param[out]    TransferLengthOut
2028                                 A pointer to a buffer to store the size in bytes
2029                                 of the data written to the buffer. Ignore it when
2030                                 IsTrustSend is TRUE.
2031 
2032   @retval EFI_SUCCESS    The data transfer is complete successfully.
2033   @return others         Some error occurs when transferring data.
2034 
2035 **/
2036 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)2037 TrustTransferAtaDevice (
2038   IN     PEI_AHCI_ATA_DEVICE_DATA    *DeviceData,
2039   IN OUT VOID                        *Buffer,
2040   IN     UINT8                       SecurityProtocolId,
2041   IN     UINT16                      SecurityProtocolSpecificData,
2042   IN     UINTN                       TransferLength,
2043   IN     BOOLEAN                     IsTrustSend,
2044   IN     UINT64                      Timeout,
2045   OUT    UINTN                       *TransferLengthOut
2046   )
2047 {
2048   PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private;
2049   EDKII_PEI_ATA_PASS_THRU_PPI         *AtaPassThru;
2050   EFI_ATA_COMMAND_BLOCK               Acb;
2051   EFI_ATA_PASS_THRU_COMMAND_PACKET    Packet;
2052   EFI_STATUS                          Status;
2053   VOID                                *NewBuffer;
2054 
2055   Private     = DeviceData->Private;
2056   AtaPassThru = &Private->AtaPassThruPpi;
2057 
2058   //
2059   // Ensure IsTrustSend are valid boolean values
2060   //
2061   ASSERT ((UINTN) IsTrustSend < 2);
2062   if ((UINTN) IsTrustSend >= 2) {
2063     return EFI_INVALID_PARAMETER;
2064   }
2065 
2066   //
2067   // Prepare for ATA command block.
2068   //
2069   ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
2070   if (TransferLength == 0) {
2071     Acb.AtaCommand    = ATA_CMD_TRUST_NON_DATA;
2072   } else {
2073     Acb.AtaCommand    = mAtaTrustCommands[IsTrustSend];
2074   }
2075   Acb.AtaFeatures      = SecurityProtocolId;
2076   Acb.AtaSectorCount   = (UINT8) (TransferLength / 512);
2077   Acb.AtaSectorNumber  = (UINT8) ((TransferLength / 512) >> 8);
2078   //
2079   // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
2080   // Here use big endian for Cylinder register.
2081   //
2082   Acb.AtaCylinderHigh  = (UINT8) SecurityProtocolSpecificData;
2083   Acb.AtaCylinderLow   = (UINT8) (SecurityProtocolSpecificData >> 8);
2084   Acb.AtaDeviceHead    = (UINT8) (BIT7 | BIT6 | BIT5 |
2085                                   (DeviceData->PortMultiplier == 0xFFFF ?
2086                                   0 : (DeviceData->PortMultiplier << 4)));
2087 
2088   //
2089   // Prepare for ATA pass through packet.
2090   //
2091   ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
2092   if (TransferLength == 0) {
2093     Packet.InTransferLength  = 0;
2094     Packet.OutTransferLength = 0;
2095     Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
2096   } else if (IsTrustSend) {
2097     //
2098     // Check the alignment of the incoming buffer prior to invoking underlying
2099     // ATA PassThru PPI.
2100     //
2101     if ((AtaPassThru->Mode->IoAlign > 1) &&
2102         !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign)) {
2103       NewBuffer = AllocateAlignedPages (
2104                     EFI_SIZE_TO_PAGES (TransferLength),
2105                     AtaPassThru->Mode->IoAlign
2106                     );
2107       if (NewBuffer == NULL) {
2108         return EFI_OUT_OF_RESOURCES;
2109       }
2110 
2111       CopyMem (NewBuffer, Buffer, TransferLength);
2112       Buffer = NewBuffer;
2113     }
2114     Packet.OutDataBuffer = Buffer;
2115     Packet.OutTransferLength = (UINT32) TransferLength;
2116     Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2117   } else {
2118     Packet.InDataBuffer = Buffer;
2119     Packet.InTransferLength = (UINT32) TransferLength;
2120     Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2121   }
2122   Packet.Asb      = NULL;
2123   Packet.Acb      = &Acb;
2124   Packet.Timeout  = Timeout;
2125   Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES;
2126 
2127   Status = AtaPassThru->PassThru (
2128                           AtaPassThru,
2129                           DeviceData->Port,
2130                           DeviceData->PortMultiplier,
2131                           &Packet
2132                           );
2133   if (TransferLengthOut != NULL) {
2134     if (!IsTrustSend) {
2135       *TransferLengthOut = Packet.InTransferLength;
2136     }
2137   }
2138   return Status;
2139 }
2140