]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
MdeModulePkg/AtaAtapiPassThru: Restart failed packets
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AhciMode.c
1 /** @file
2 The file for AHCI mode of ATA host controller.
3
4 Copyright (c) 2010 - 2020, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "AtaAtapiPassThru.h"
11
12 /**
13 Read AHCI Operation register.
14
15 @param PciIo The PCI IO protocol instance.
16 @param Offset The operation register offset.
17
18 @return The register content read.
19
20 **/
21 UINT32
22 EFIAPI
23 AhciReadReg (
24 IN EFI_PCI_IO_PROTOCOL *PciIo,
25 IN UINT32 Offset
26 )
27 {
28 UINT32 Data;
29
30 ASSERT (PciIo != NULL);
31
32 Data = 0;
33
34 PciIo->Mem.Read (
35 PciIo,
36 EfiPciIoWidthUint32,
37 EFI_AHCI_BAR_INDEX,
38 (UINT64) Offset,
39 1,
40 &Data
41 );
42
43 return Data;
44 }
45
46 /**
47 Write AHCI Operation register.
48
49 @param PciIo The PCI IO protocol instance.
50 @param Offset The operation register offset.
51 @param Data The data used to write down.
52
53 **/
54 VOID
55 EFIAPI
56 AhciWriteReg (
57 IN EFI_PCI_IO_PROTOCOL *PciIo,
58 IN UINT32 Offset,
59 IN UINT32 Data
60 )
61 {
62 ASSERT (PciIo != NULL);
63
64 PciIo->Mem.Write (
65 PciIo,
66 EfiPciIoWidthUint32,
67 EFI_AHCI_BAR_INDEX,
68 (UINT64) Offset,
69 1,
70 &Data
71 );
72
73 return ;
74 }
75
76 /**
77 Do AND operation with the value of AHCI Operation register.
78
79 @param PciIo The PCI IO protocol instance.
80 @param Offset The operation register offset.
81 @param AndData The data used to do AND operation.
82
83 **/
84 VOID
85 EFIAPI
86 AhciAndReg (
87 IN EFI_PCI_IO_PROTOCOL *PciIo,
88 IN UINT32 Offset,
89 IN UINT32 AndData
90 )
91 {
92 UINT32 Data;
93
94 ASSERT (PciIo != NULL);
95
96 Data = AhciReadReg (PciIo, Offset);
97
98 Data &= AndData;
99
100 AhciWriteReg (PciIo, Offset, Data);
101 }
102
103 /**
104 Do OR operation with the value of AHCI Operation register.
105
106 @param PciIo The PCI IO protocol instance.
107 @param Offset The operation register offset.
108 @param OrData The data used to do OR operation.
109
110 **/
111 VOID
112 EFIAPI
113 AhciOrReg (
114 IN EFI_PCI_IO_PROTOCOL *PciIo,
115 IN UINT32 Offset,
116 IN UINT32 OrData
117 )
118 {
119 UINT32 Data;
120
121 ASSERT (PciIo != NULL);
122
123 Data = AhciReadReg (PciIo, Offset);
124
125 Data |= OrData;
126
127 AhciWriteReg (PciIo, Offset, Data);
128 }
129
130 /**
131 Wait for the value of the specified MMIO register set to the test value.
132
133 @param PciIo The PCI IO protocol instance.
134 @param Offset The MMIO address to test.
135 @param MaskValue The mask value of memory.
136 @param TestValue The test value of memory.
137 @param Timeout The time out value for wait memory set, uses 100ns as a unit.
138
139 @retval EFI_TIMEOUT The MMIO setting is time out.
140 @retval EFI_SUCCESS The MMIO is correct set.
141
142 **/
143 EFI_STATUS
144 EFIAPI
145 AhciWaitMmioSet (
146 IN EFI_PCI_IO_PROTOCOL *PciIo,
147 IN UINTN Offset,
148 IN UINT32 MaskValue,
149 IN UINT32 TestValue,
150 IN UINT64 Timeout
151 )
152 {
153 UINT32 Value;
154 UINT64 Delay;
155 BOOLEAN InfiniteWait;
156
157 if (Timeout == 0) {
158 InfiniteWait = TRUE;
159 } else {
160 InfiniteWait = FALSE;
161 }
162
163 Delay = DivU64x32 (Timeout, 1000) + 1;
164
165 do {
166 //
167 // Access PCI MMIO space to see if the value is the tested one.
168 //
169 Value = AhciReadReg (PciIo, (UINT32) Offset) & MaskValue;
170
171 if (Value == TestValue) {
172 return EFI_SUCCESS;
173 }
174
175 //
176 // Stall for 100 microseconds.
177 //
178 MicroSecondDelay (100);
179
180 Delay--;
181
182 } while (InfiniteWait || (Delay > 0));
183
184 return EFI_TIMEOUT;
185 }
186
187 /**
188 Wait for the value of the specified system memory set to the test value.
189
190 @param Address The system memory address to test.
191 @param MaskValue The mask value of memory.
192 @param TestValue The test value of memory.
193 @param Timeout The time out value for wait memory set, uses 100ns as a unit.
194
195 @retval EFI_TIMEOUT The system memory setting is time out.
196 @retval EFI_SUCCESS The system memory is correct set.
197
198 **/
199 EFI_STATUS
200 EFIAPI
201 AhciWaitMemSet (
202 IN EFI_PHYSICAL_ADDRESS Address,
203 IN UINT32 MaskValue,
204 IN UINT32 TestValue,
205 IN UINT64 Timeout
206 )
207 {
208 UINT32 Value;
209 UINT64 Delay;
210 BOOLEAN InfiniteWait;
211
212 if (Timeout == 0) {
213 InfiniteWait = TRUE;
214 } else {
215 InfiniteWait = FALSE;
216 }
217
218 Delay = DivU64x32 (Timeout, 1000) + 1;
219
220 do {
221 //
222 // Access system memory to see if the value is the tested one.
223 //
224 // The system memory pointed by Address will be updated by the
225 // SATA Host Controller, "volatile" is introduced to prevent
226 // compiler from optimizing the access to the memory address
227 // to only read once.
228 //
229 Value = *(volatile UINT32 *) (UINTN) Address;
230 Value &= MaskValue;
231
232 if (Value == TestValue) {
233 return EFI_SUCCESS;
234 }
235
236 //
237 // Stall for 100 microseconds.
238 //
239 MicroSecondDelay (100);
240
241 Delay--;
242
243 } while (InfiniteWait || (Delay > 0));
244
245 return EFI_TIMEOUT;
246 }
247
248 /**
249 Check the memory status to the test value.
250
251 @param[in] Address The memory address to test.
252 @param[in] MaskValue The mask value of memory.
253 @param[in] TestValue The test value of memory.
254
255 @retval EFI_NOT_READY The memory is not set.
256 @retval EFI_SUCCESS The memory is correct set.
257 **/
258 EFI_STATUS
259 EFIAPI
260 AhciCheckMemSet (
261 IN UINTN Address,
262 IN UINT32 MaskValue,
263 IN UINT32 TestValue
264 )
265 {
266 UINT32 Value;
267
268 Value = *(volatile UINT32 *) Address;
269 Value &= MaskValue;
270
271 if (Value == TestValue) {
272 return EFI_SUCCESS;
273 }
274
275 return EFI_NOT_READY;
276 }
277
278
279 /**
280
281 Clear the port interrupt and error status. It will also clear
282 HBA interrupt status.
283
284 @param PciIo The PCI IO protocol instance.
285 @param Port The number of port.
286
287 **/
288 VOID
289 EFIAPI
290 AhciClearPortStatus (
291 IN EFI_PCI_IO_PROTOCOL *PciIo,
292 IN UINT8 Port
293 )
294 {
295 UINT32 Offset;
296
297 //
298 // Clear any error status
299 //
300 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
301 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
302
303 //
304 // Clear any port interrupt status
305 //
306 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
307 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
308
309 //
310 // Clear any HBA interrupt status
311 //
312 AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));
313 }
314
315 /**
316 This function is used to dump the Status Registers and if there is ERR bit set
317 in the Status Register, the Error Register's value is also be dumped.
318
319 @param PciIo The PCI IO protocol instance.
320 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
321 @param Port The number of port.
322 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
323
324 **/
325 VOID
326 EFIAPI
327 AhciDumpPortStatus (
328 IN EFI_PCI_IO_PROTOCOL *PciIo,
329 IN EFI_AHCI_REGISTERS *AhciRegisters,
330 IN UINT8 Port,
331 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
332 )
333 {
334 UINTN Offset;
335 UINT32 Data;
336 UINTN FisBaseAddr;
337 EFI_STATUS Status;
338
339 ASSERT (PciIo != NULL);
340
341 if (AtaStatusBlock != NULL) {
342 ZeroMem (AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
343
344 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
345 Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
346
347 Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H);
348 if (!EFI_ERROR (Status)) {
349 //
350 // If D2H FIS is received, update StatusBlock with its content.
351 //
352 CopyMem (AtaStatusBlock, (UINT8 *)Offset, sizeof (EFI_ATA_STATUS_BLOCK));
353 } else {
354 //
355 // If D2H FIS is not received, only update Status & Error field through PxTFD
356 // as there is no other way to get the content of the Shadow Register Block.
357 //
358 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
359 Data = AhciReadReg (PciIo, (UINT32)Offset);
360
361 AtaStatusBlock->AtaStatus = (UINT8)Data;
362 if ((AtaStatusBlock->AtaStatus & BIT0) != 0) {
363 AtaStatusBlock->AtaError = (UINT8)(Data >> 8);
364 }
365 }
366 }
367 }
368
369
370 /**
371 Enable the FIS running for giving port.
372
373 @param PciIo The PCI IO protocol instance.
374 @param Port The number of port.
375 @param Timeout The timeout value of enabling FIS, uses 100ns as a unit.
376
377 @retval EFI_DEVICE_ERROR The FIS enable setting fails.
378 @retval EFI_TIMEOUT The FIS enable setting is time out.
379 @retval EFI_SUCCESS The FIS enable successfully.
380
381 **/
382 EFI_STATUS
383 EFIAPI
384 AhciEnableFisReceive (
385 IN EFI_PCI_IO_PROTOCOL *PciIo,
386 IN UINT8 Port,
387 IN UINT64 Timeout
388 )
389 {
390 UINT32 Offset;
391
392 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
393 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
394
395 return EFI_SUCCESS;
396 }
397
398 /**
399 Disable the FIS running for giving port.
400
401 @param PciIo The PCI IO protocol instance.
402 @param Port The number of port.
403 @param Timeout The timeout value of disabling FIS, uses 100ns as a unit.
404
405 @retval EFI_DEVICE_ERROR The FIS disable setting fails.
406 @retval EFI_TIMEOUT The FIS disable setting is time out.
407 @retval EFI_UNSUPPORTED The port is in running state.
408 @retval EFI_SUCCESS The FIS disable successfully.
409
410 **/
411 EFI_STATUS
412 EFIAPI
413 AhciDisableFisReceive (
414 IN EFI_PCI_IO_PROTOCOL *PciIo,
415 IN UINT8 Port,
416 IN UINT64 Timeout
417 )
418 {
419 UINT32 Offset;
420 UINT32 Data;
421
422 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
423 Data = AhciReadReg (PciIo, Offset);
424
425 //
426 // Before disabling Fis receive, the DMA engine of the port should NOT be in running status.
427 //
428 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {
429 return EFI_UNSUPPORTED;
430 }
431
432 //
433 // Check if the Fis receive DMA engine for the port is running.
434 //
435 if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) {
436 return EFI_SUCCESS;
437 }
438
439 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));
440
441 return AhciWaitMmioSet (
442 PciIo,
443 Offset,
444 EFI_AHCI_PORT_CMD_FR,
445 0,
446 Timeout
447 );
448 }
449
450
451
452 /**
453 Build the command list, command table and prepare the fis receiver.
454
455 @param PciIo The PCI IO protocol instance.
456 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
457 @param Port The number of port.
458 @param PortMultiplier The timeout value of stop.
459 @param CommandFis The control fis will be used for the transfer.
460 @param CommandList The command list will be used for the transfer.
461 @param AtapiCommand The atapi command will be used for the transfer.
462 @param AtapiCommandLength The length of the atapi command.
463 @param CommandSlotNumber The command slot will be used for the transfer.
464 @param DataPhysicalAddr The pointer to the data buffer pci bus master address.
465 @param DataLength The data count to be transferred.
466
467 **/
468 VOID
469 EFIAPI
470 AhciBuildCommand (
471 IN EFI_PCI_IO_PROTOCOL *PciIo,
472 IN EFI_AHCI_REGISTERS *AhciRegisters,
473 IN UINT8 Port,
474 IN UINT8 PortMultiplier,
475 IN EFI_AHCI_COMMAND_FIS *CommandFis,
476 IN EFI_AHCI_COMMAND_LIST *CommandList,
477 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
478 IN UINT8 AtapiCommandLength,
479 IN UINT8 CommandSlotNumber,
480 IN OUT VOID *DataPhysicalAddr,
481 IN UINT32 DataLength
482 )
483 {
484 UINT64 BaseAddr;
485 UINT32 PrdtNumber;
486 UINT32 PrdtIndex;
487 UINTN RemainedData;
488 UINTN MemAddr;
489 DATA_64 Data64;
490 UINT32 Offset;
491
492 //
493 // Filling the PRDT
494 //
495 PrdtNumber = (UINT32)DivU64x32 (((UINT64)DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1), EFI_AHCI_MAX_DATA_PER_PRDT);
496
497 //
498 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
499 // It also limits that the maximum amount of the PRDT entry in the command table
500 // is 65535.
501 //
502 ASSERT (PrdtNumber <= 65535);
503
504 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
505
506 BaseAddr = Data64.Uint64;
507
508 ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
509
510 ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
511
512 CommandFis->AhciCFisPmNum = PortMultiplier;
513
514 CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
515
516 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
517 if (AtapiCommand != NULL) {
518 CopyMem (
519 &AhciRegisters->AhciCommandTable->AtapiCmd,
520 AtapiCommand,
521 AtapiCommandLength
522 );
523
524 CommandList->AhciCmdA = 1;
525 CommandList->AhciCmdP = 1;
526
527 AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
528 } else {
529 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
530 }
531
532 RemainedData = (UINTN) DataLength;
533 MemAddr = (UINTN) DataPhysicalAddr;
534 CommandList->AhciCmdPrdtl = PrdtNumber;
535
536 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
537 if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {
538 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
539 } else {
540 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;
541 }
542
543 Data64.Uint64 = (UINT64)MemAddr;
544 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
545 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
546 RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
547 MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT;
548 }
549
550 //
551 // Set the last PRDT to Interrupt On Complete
552 //
553 if (PrdtNumber > 0) {
554 AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
555 }
556
557 CopyMem (
558 (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
559 CommandList,
560 sizeof (EFI_AHCI_COMMAND_LIST)
561 );
562
563 Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr;
564 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
565 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
566 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;
567
568 }
569
570 /**
571 Build a command FIS.
572
573 @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure.
574 @param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure.
575
576 **/
577 VOID
578 EFIAPI
579 AhciBuildCommandFis (
580 IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,
581 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
582 )
583 {
584 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
585
586 CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D;
587 //
588 // Indicator it's a command
589 //
590 CmdFis->AhciCFisCmdInd = 0x1;
591 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
592
593 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
594 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
595
596 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
597 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
598
599 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
600 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
601
602 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
603 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
604
605 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
606 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
607
608 CmdFis->AhciCFisDevHead = (UINT8) (AtaCommandBlock->AtaDeviceHead | 0xE0);
609 }
610
611 /**
612 Wait until SATA device reports it is ready for operation.
613
614 @param[in] PciIo Pointer to AHCI controller PciIo.
615 @param[in] Port SATA port index on which to reset.
616
617 @retval EFI_SUCCESS Device ready for operation.
618 @retval EFI_TIMEOUT Device failed to get ready within required period.
619 **/
620 EFI_STATUS
621 AhciWaitDeviceReady (
622 IN EFI_PCI_IO_PROTOCOL *PciIo,
623 IN UINT8 Port
624 )
625 {
626 UINT32 PhyDetectDelay;
627 UINT32 Data;
628 UINT32 Offset;
629
630 //
631 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
632 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
633 //
634 PhyDetectDelay = 16 * 1000;
635 do {
636 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
637 if (AhciReadReg(PciIo, Offset) != 0) {
638 AhciWriteReg (PciIo, Offset, AhciReadReg(PciIo, Offset));
639 }
640 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
641
642 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_TFD_MASK;
643 if (Data == 0) {
644 break;
645 }
646
647 MicroSecondDelay (1000);
648 PhyDetectDelay--;
649 } while (PhyDetectDelay > 0);
650
651 if (PhyDetectDelay == 0) {
652 DEBUG ((DEBUG_ERROR, "Port %d Device not ready (TFD=0x%X)\n", Port, Data));
653 return EFI_TIMEOUT;
654 } else {
655 return EFI_SUCCESS;
656 }
657 }
658
659
660 /**
661 Reset the SATA port. Algorithm follows AHCI spec 1.3.1 section 10.4.2
662
663 @param[in] PciIo Pointer to AHCI controller PciIo.
664 @param[in] Port SATA port index on which to reset.
665
666 @retval EFI_SUCCESS Port reset.
667 @retval Others Failed to reset the port.
668 **/
669 EFI_STATUS
670 AhciResetPort (
671 IN EFI_PCI_IO_PROTOCOL *PciIo,
672 IN UINT8 Port
673 )
674 {
675 UINT32 Offset;
676 EFI_STATUS Status;
677
678 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
679 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);
680 //
681 // SW is required to keep DET set to 0x1 at least for 1 milisecond to ensure that
682 // at least one COMRESET signal is sent.
683 //
684 MicroSecondDelay(1000);
685 AhciAndReg (PciIo, Offset, ~(UINT32)EFI_AHCI_PORT_SSTS_DET_MASK);
686
687 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
688 Status = AhciWaitMmioSet (PciIo, Offset, EFI_AHCI_PORT_SSTS_DET_MASK, EFI_AHCI_PORT_SSTS_DET_PCE, ATA_ATAPI_TIMEOUT);
689 if (EFI_ERROR (Status)) {
690 return Status;
691 }
692
693 return AhciWaitDeviceReady (PciIo, Port);
694 }
695
696 /**
697 Recovers the SATA port from error condition.
698 This function implements algorithm described in
699 AHCI spec 1.3.1 section 6.2.2
700
701 @param[in] PciIo Pointer to AHCI controller PciIo.
702 @param[in] Port SATA port index on which to check.
703
704 @retval EFI_SUCCESS Port recovered.
705 @retval Others Failed to recover port.
706 **/
707 EFI_STATUS
708 AhciRecoverPortError (
709 IN EFI_PCI_IO_PROTOCOL *PciIo,
710 IN UINT8 Port
711 )
712 {
713 UINT32 Offset;
714 UINT32 PortInterrupt;
715 UINT32 PortTfd;
716 EFI_STATUS Status;
717
718 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
719 PortInterrupt = AhciReadReg (PciIo, Offset);
720 if ((PortInterrupt & EFI_AHCI_PORT_IS_FATAL_ERROR_MASK) == 0) {
721 //
722 // No fatal error detected. Exit with success as port should still be operational.
723 // No need to clear IS as it will be cleared when the next command starts.
724 //
725 return EFI_SUCCESS;
726 }
727
728 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
729 AhciAndReg (PciIo, Offset, ~(UINT32)EFI_AHCI_PORT_CMD_ST);
730
731 Status = AhciWaitMmioSet (PciIo, Offset, EFI_AHCI_PORT_CMD_CR, 0, ATA_ATAPI_TIMEOUT);
732 if (EFI_ERROR (Status)) {
733 DEBUG ((DEBUG_ERROR, "Ahci port %d is in hung state, aborting recovery\n", Port));
734 return Status;
735 }
736
737 //
738 // If TFD.BSY or TFD.DRQ is still set it means that drive is hung and software has
739 // to reset it before sending any additional commands.
740 //
741 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
742 PortTfd = AhciReadReg (PciIo, Offset);
743 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
744 Status = AhciResetPort (PciIo, Port);
745 if (EFI_ERROR (Status)) {
746 DEBUG ((DEBUG_ERROR, "Failed to reset the port %d\n", Port));
747 }
748 }
749
750 return EFI_SUCCESS;
751 }
752
753 /**
754 Checks if specified FIS has been received.
755
756 @param[in] PciIo Pointer to AHCI controller PciIo.
757 @param[in] Port SATA port index on which to check.
758 @param[in] FisType FIS type for which to check.
759
760 @retval EFI_SUCCESS FIS received.
761 @retval EFI_NOT_READY FIS not received yet.
762 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
763 **/
764 EFI_STATUS
765 AhciCheckFisReceived (
766 IN EFI_PCI_IO_PROTOCOL *PciIo,
767 IN UINT8 Port,
768 IN SATA_FIS_TYPE FisType
769 )
770 {
771 UINT32 Offset;
772 UINT32 PortInterrupt;
773 UINT32 PortTfd;
774
775 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
776 PortInterrupt = AhciReadReg (PciIo, Offset);
777 if ((PortInterrupt & EFI_AHCI_PORT_IS_ERROR_MASK) != 0) {
778 DEBUG ((DEBUG_ERROR, "AHCI: Error interrupt reported PxIS: %X\n", PortInterrupt));
779 return EFI_DEVICE_ERROR;
780 }
781 //
782 // For PIO setup FIS - According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered.
783 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from device
784 // after the transaction is finished successfully.
785 // To get better device compatibilities, we further check if the PxTFD's ERR bit is set.
786 // By this way, we can know if there is a real error happened.
787 //
788 if (((FisType == SataFisD2H) && ((PortInterrupt & EFI_AHCI_PORT_IS_DHRS) != 0)) ||
789 ((FisType == SataFisPioSetup) && (PortInterrupt & (EFI_AHCI_PORT_IS_PSS | EFI_AHCI_PORT_IS_DHRS)) != 0) ||
790 ((FisType == SataFisDmaSetup) && (PortInterrupt & (EFI_AHCI_PORT_IS_DSS | EFI_AHCI_PORT_IS_DHRS)) != 0)) {
791 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
792 PortTfd = AhciReadReg (PciIo, (UINT32) Offset);
793 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
794 return EFI_DEVICE_ERROR;
795 } else {
796 return EFI_SUCCESS;
797 }
798 }
799
800 return EFI_NOT_READY;
801 }
802
803 /**
804 Waits until specified FIS has been received.
805
806 @param[in] PciIo Pointer to AHCI controller PciIo.
807 @param[in] Port SATA port index on which to check.
808 @param[in] Timeout Time after which function should stop polling.
809 @param[in] FisType FIS type for which to check.
810
811 @retval EFI_SUCCESS FIS received.
812 @retval EFI_TIMEOUT FIS failed to arrive within a specified time period.
813 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
814 **/
815 EFI_STATUS
816 AhciWaitUntilFisReceived (
817 IN EFI_PCI_IO_PROTOCOL *PciIo,
818 IN UINT8 Port,
819 IN UINT64 Timeout,
820 IN SATA_FIS_TYPE FisType
821 )
822 {
823 EFI_STATUS Status;
824 BOOLEAN InfiniteWait;
825 UINT64 Delay;
826
827 Delay = DivU64x32 (Timeout, 1000) + 1;
828 if (Timeout == 0) {
829 InfiniteWait = TRUE;
830 } else {
831 InfiniteWait = FALSE;
832 }
833
834 do {
835 Status = AhciCheckFisReceived (PciIo, Port, FisType);
836 if (Status != EFI_NOT_READY) {
837 return Status;
838 }
839 //
840 // Stall for 100 microseconds.
841 //
842 MicroSecondDelay (100);
843 Delay--;
844 } while (InfiniteWait || (Delay > 0));
845
846 return EFI_TIMEOUT;
847 }
848
849 /**
850 Start a PIO data transfer on specific port.
851
852 @param[in] PciIo The PCI IO protocol instance.
853 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
854 @param[in] Port The number of port.
855 @param[in] PortMultiplier The timeout value of stop.
856 @param[in] AtapiCommand The atapi command will be used for the
857 transfer.
858 @param[in] AtapiCommandLength The length of the atapi command.
859 @param[in] Read The transfer direction.
860 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
861 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
862 @param[in, out] MemoryAddr The pointer to the data buffer.
863 @param[in] DataCount The data count to be transferred.
864 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
865 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
866 used by non-blocking mode.
867
868 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
869 @retval EFI_TIMEOUT The operation is time out.
870 @retval EFI_UNSUPPORTED The device is not ready for transfer.
871 @retval EFI_SUCCESS The PIO data transfer executes successfully.
872
873 **/
874 EFI_STATUS
875 EFIAPI
876 AhciPioTransfer (
877 IN EFI_PCI_IO_PROTOCOL *PciIo,
878 IN EFI_AHCI_REGISTERS *AhciRegisters,
879 IN UINT8 Port,
880 IN UINT8 PortMultiplier,
881 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
882 IN UINT8 AtapiCommandLength,
883 IN BOOLEAN Read,
884 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
885 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
886 IN OUT VOID *MemoryAddr,
887 IN UINT32 DataCount,
888 IN UINT64 Timeout,
889 IN ATA_NONBLOCK_TASK *Task
890 )
891 {
892 EFI_STATUS Status;
893 EFI_PHYSICAL_ADDRESS PhyAddr;
894 VOID *Map;
895 UINTN MapLength;
896 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
897 EFI_AHCI_COMMAND_FIS CFis;
898 EFI_AHCI_COMMAND_LIST CmdList;
899 UINT32 PrdCount;
900 UINT32 Retry;
901
902 if (Read) {
903 Flag = EfiPciIoOperationBusMasterWrite;
904 } else {
905 Flag = EfiPciIoOperationBusMasterRead;
906 }
907
908 //
909 // construct command list and command table with pci bus address
910 //
911 MapLength = DataCount;
912 Status = PciIo->Map (
913 PciIo,
914 Flag,
915 MemoryAddr,
916 &MapLength,
917 &PhyAddr,
918 &Map
919 );
920
921 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
922 return EFI_BAD_BUFFER_SIZE;
923 }
924
925 //
926 // Package read needed
927 //
928 AhciBuildCommandFis (&CFis, AtaCommandBlock);
929
930 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
931
932 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
933 CmdList.AhciCmdW = Read ? 0 : 1;
934
935 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
936 AhciBuildCommand (
937 PciIo,
938 AhciRegisters,
939 Port,
940 PortMultiplier,
941 &CFis,
942 &CmdList,
943 AtapiCommand,
944 AtapiCommandLength,
945 0,
946 (VOID *)(UINTN)PhyAddr,
947 DataCount
948 );
949
950 Status = AhciStartCommand (
951 PciIo,
952 Port,
953 0,
954 Timeout
955 );
956 if (EFI_ERROR (Status)) {
957 break;
958 }
959
960 if (Read && (AtapiCommand == 0)) {
961 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisPioSetup);
962 if (Status == EFI_SUCCESS) {
963 PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
964 if (PrdCount == DataCount) {
965 Status = EFI_SUCCESS;
966 } else {
967 Status = EFI_DEVICE_ERROR;
968 }
969 }
970 } else {
971 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
972 }
973
974 if (Status == EFI_DEVICE_ERROR) {
975 DEBUG ((DEBUG_ERROR, "PIO command failed at retry %d\n", Retry));
976 Status = AhciRecoverPortError (PciIo, Port);
977 if (EFI_ERROR (Status)) {
978 break;
979 }
980 } else {
981 break;
982 }
983 }
984
985 AhciStopCommand (
986 PciIo,
987 Port,
988 Timeout
989 );
990
991 AhciDisableFisReceive (
992 PciIo,
993 Port,
994 Timeout
995 );
996
997 PciIo->Unmap (
998 PciIo,
999 Map
1000 );
1001
1002 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1003 return Status;
1004 }
1005
1006 /**
1007 Start a DMA data transfer on specific port
1008
1009 @param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.
1010 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1011 @param[in] Port The number of port.
1012 @param[in] PortMultiplier The timeout value of stop.
1013 @param[in] AtapiCommand The atapi command will be used for the
1014 transfer.
1015 @param[in] AtapiCommandLength The length of the atapi command.
1016 @param[in] Read The transfer direction.
1017 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
1018 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
1019 @param[in, out] MemoryAddr The pointer to the data buffer.
1020 @param[in] DataCount The data count to be transferred.
1021 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
1022 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1023 used by non-blocking mode.
1024
1025 @retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
1026 @retval EFI_TIMEOUT The operation is time out.
1027 @retval EFI_UNSUPPORTED The device is not ready for transfer.
1028 @retval EFI_SUCCESS The DMA data transfer executes successfully.
1029
1030 **/
1031 EFI_STATUS
1032 EFIAPI
1033 AhciDmaTransfer (
1034 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
1035 IN EFI_AHCI_REGISTERS *AhciRegisters,
1036 IN UINT8 Port,
1037 IN UINT8 PortMultiplier,
1038 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
1039 IN UINT8 AtapiCommandLength,
1040 IN BOOLEAN Read,
1041 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1042 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1043 IN OUT VOID *MemoryAddr,
1044 IN UINT32 DataCount,
1045 IN UINT64 Timeout,
1046 IN ATA_NONBLOCK_TASK *Task
1047 )
1048 {
1049 EFI_STATUS Status;
1050 EFI_PHYSICAL_ADDRESS PhyAddr;
1051 VOID *Map;
1052 UINTN MapLength;
1053 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
1054 EFI_AHCI_COMMAND_FIS CFis;
1055 EFI_AHCI_COMMAND_LIST CmdList;
1056 EFI_PCI_IO_PROTOCOL *PciIo;
1057 EFI_TPL OldTpl;
1058 UINT32 Retry;
1059
1060 Map = NULL;
1061 PciIo = Instance->PciIo;
1062
1063 if (PciIo == NULL) {
1064 return EFI_INVALID_PARAMETER;
1065 }
1066
1067 //
1068 // DMA buffer allocation. Needs to be done only once for both sync and async
1069 // DMA transfers irrespective of number of retries.
1070 //
1071 if ((Task == NULL) || ((Task != NULL) && (Task->Map == NULL))) {
1072 if (Read) {
1073 Flag = EfiPciIoOperationBusMasterWrite;
1074 } else {
1075 Flag = EfiPciIoOperationBusMasterRead;
1076 }
1077
1078 MapLength = DataCount;
1079 Status = PciIo->Map (
1080 PciIo,
1081 Flag,
1082 MemoryAddr,
1083 &MapLength,
1084 &PhyAddr,
1085 &Map
1086 );
1087
1088 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
1089 return EFI_BAD_BUFFER_SIZE;
1090 }
1091 if (Task != NULL) {
1092 Task->Map = Map;
1093 }
1094 }
1095
1096 if (Task == NULL || (Task != NULL && !Task->IsStart)) {
1097 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1098
1099 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1100
1101 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1102 CmdList.AhciCmdW = Read ? 0 : 1;
1103 }
1104
1105 if (Task == NULL) {
1106 //
1107 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
1108 // BlockIO tasks.
1109 // Delay 100us to simulate the blocking time out checking.
1110 //
1111 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1112 while (!IsListEmpty (&Instance->NonBlockingTaskList)) {
1113 AsyncNonBlockingTransferRoutine (NULL, Instance);
1114 //
1115 // Stall for 100us.
1116 //
1117 MicroSecondDelay (100);
1118 }
1119 gBS->RestoreTPL (OldTpl);
1120 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
1121 AhciBuildCommand (
1122 PciIo,
1123 AhciRegisters,
1124 Port,
1125 PortMultiplier,
1126 &CFis,
1127 &CmdList,
1128 AtapiCommand,
1129 AtapiCommandLength,
1130 0,
1131 (VOID *)(UINTN)PhyAddr,
1132 DataCount
1133 );
1134
1135 Status = AhciStartCommand (
1136 PciIo,
1137 Port,
1138 0,
1139 Timeout
1140 );
1141 if (EFI_ERROR (Status)) {
1142 break;
1143 }
1144 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1145 if (Status == EFI_DEVICE_ERROR) {
1146 DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Retry));
1147 Status = AhciRecoverPortError (PciIo, Port);
1148 if (EFI_ERROR (Status)) {
1149 break;
1150 }
1151 } else {
1152 break;
1153 }
1154 }
1155 } else {
1156 if (!Task->IsStart) {
1157 AhciBuildCommand (
1158 PciIo,
1159 AhciRegisters,
1160 Port,
1161 PortMultiplier,
1162 &CFis,
1163 &CmdList,
1164 AtapiCommand,
1165 AtapiCommandLength,
1166 0,
1167 (VOID *)(UINTN)PhyAddr,
1168 DataCount
1169 );
1170
1171 Status = AhciStartCommand (
1172 PciIo,
1173 Port,
1174 0,
1175 Timeout
1176 );
1177 if (!EFI_ERROR (Status)) {
1178 Task->IsStart = TRUE;
1179 }
1180 }
1181 if (Task->IsStart) {
1182 Status = AhciCheckFisReceived (PciIo, Port, SataFisD2H);
1183 if (Status == EFI_DEVICE_ERROR) {
1184 DEBUG ((DEBUG_ERROR, "DMA command failed at retry: %d\n", Task->RetryTimes));
1185 Status = AhciRecoverPortError (PciIo, Port);
1186 //
1187 // If recovery passed mark the Task as not started and change the status
1188 // to EFI_NOT_READY. This will make the higher level call this function again
1189 // and on next call the command will be re-issued due to IsStart being FALSE.
1190 // This also makes the next condition decrement the RetryTimes.
1191 //
1192 if (Status == EFI_SUCCESS) {
1193 Task->IsStart = FALSE;
1194 Status = EFI_NOT_READY;
1195 }
1196 }
1197
1198 if (Status == EFI_NOT_READY) {
1199 if (!Task->InfiniteWait && Task->RetryTimes == 0) {
1200 Status = EFI_TIMEOUT;
1201 } else {
1202 Task->RetryTimes--;
1203 }
1204 }
1205 }
1206 }
1207
1208 //
1209 // For Blocking mode, the command should be stopped, the Fis should be disabled
1210 // and the PciIo should be unmapped.
1211 // For non-blocking mode, only when a error is happened (if the return status is
1212 // EFI_NOT_READY that means the command doesn't finished, try again.), first do the
1213 // context cleanup, then set the packet's Asb status.
1214 //
1215 if (Task == NULL ||
1216 ((Task != NULL) && (Status != EFI_NOT_READY))
1217 ) {
1218 AhciStopCommand (
1219 PciIo,
1220 Port,
1221 Timeout
1222 );
1223
1224 AhciDisableFisReceive (
1225 PciIo,
1226 Port,
1227 Timeout
1228 );
1229
1230 PciIo->Unmap (
1231 PciIo,
1232 (Task != NULL) ? Task->Map : Map
1233 );
1234
1235 if (Task != NULL) {
1236 Task->Packet->Asb->AtaStatus = 0x01;
1237 }
1238 }
1239
1240 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1241 return Status;
1242 }
1243
1244 /**
1245 Start a non data transfer on specific port.
1246
1247 @param[in] PciIo The PCI IO protocol instance.
1248 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1249 @param[in] Port The number of port.
1250 @param[in] PortMultiplier The timeout value of stop.
1251 @param[in] AtapiCommand The atapi command will be used for the
1252 transfer.
1253 @param[in] AtapiCommandLength The length of the atapi command.
1254 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
1255 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
1256 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
1257 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1258 used by non-blocking mode.
1259
1260 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
1261 @retval EFI_TIMEOUT The operation is time out.
1262 @retval EFI_UNSUPPORTED The device is not ready for transfer.
1263 @retval EFI_SUCCESS The non data transfer executes successfully.
1264
1265 **/
1266 EFI_STATUS
1267 EFIAPI
1268 AhciNonDataTransfer (
1269 IN EFI_PCI_IO_PROTOCOL *PciIo,
1270 IN EFI_AHCI_REGISTERS *AhciRegisters,
1271 IN UINT8 Port,
1272 IN UINT8 PortMultiplier,
1273 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
1274 IN UINT8 AtapiCommandLength,
1275 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1276 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1277 IN UINT64 Timeout,
1278 IN ATA_NONBLOCK_TASK *Task
1279 )
1280 {
1281 EFI_STATUS Status;
1282 EFI_AHCI_COMMAND_FIS CFis;
1283 EFI_AHCI_COMMAND_LIST CmdList;
1284 UINT32 Retry;
1285
1286 //
1287 // Package read needed
1288 //
1289 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1290
1291 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1292
1293 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1294
1295 for (Retry = 0; Retry < AHCI_COMMAND_RETRIES; Retry++) {
1296 AhciBuildCommand (
1297 PciIo,
1298 AhciRegisters,
1299 Port,
1300 PortMultiplier,
1301 &CFis,
1302 &CmdList,
1303 AtapiCommand,
1304 AtapiCommandLength,
1305 0,
1306 NULL,
1307 0
1308 );
1309
1310 Status = AhciStartCommand (
1311 PciIo,
1312 Port,
1313 0,
1314 Timeout
1315 );
1316 if (EFI_ERROR (Status)) {
1317 break;
1318 }
1319
1320 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1321 if (Status == EFI_DEVICE_ERROR) {
1322 DEBUG ((DEBUG_ERROR, "Non data transfer failed at retry %d\n", Retry));
1323 Status = AhciRecoverPortError (PciIo, Port);
1324 if (EFI_ERROR (Status)) {
1325 break;
1326 }
1327 } else {
1328 break;
1329 }
1330 }
1331
1332 AhciStopCommand (
1333 PciIo,
1334 Port,
1335 Timeout
1336 );
1337
1338 AhciDisableFisReceive (
1339 PciIo,
1340 Port,
1341 Timeout
1342 );
1343
1344 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1345
1346 return Status;
1347 }
1348
1349 /**
1350 Stop command running for giving port
1351
1352 @param PciIo The PCI IO protocol instance.
1353 @param Port The number of port.
1354 @param Timeout The timeout value of stop, uses 100ns as a unit.
1355
1356 @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
1357 @retval EFI_TIMEOUT The operation is time out.
1358 @retval EFI_SUCCESS The command stop successfully.
1359
1360 **/
1361 EFI_STATUS
1362 EFIAPI
1363 AhciStopCommand (
1364 IN EFI_PCI_IO_PROTOCOL *PciIo,
1365 IN UINT8 Port,
1366 IN UINT64 Timeout
1367 )
1368 {
1369 UINT32 Offset;
1370 UINT32 Data;
1371
1372 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1373 Data = AhciReadReg (PciIo, Offset);
1374
1375 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) {
1376 return EFI_SUCCESS;
1377 }
1378
1379 if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
1380 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));
1381 }
1382
1383 return AhciWaitMmioSet (
1384 PciIo,
1385 Offset,
1386 EFI_AHCI_PORT_CMD_CR,
1387 0,
1388 Timeout
1389 );
1390 }
1391
1392 /**
1393 Start command for give slot on specific port.
1394
1395 @param PciIo The PCI IO protocol instance.
1396 @param Port The number of port.
1397 @param CommandSlot The number of Command Slot.
1398 @param Timeout The timeout value of start, uses 100ns as a unit.
1399
1400 @retval EFI_DEVICE_ERROR The command start unsuccessfully.
1401 @retval EFI_TIMEOUT The operation is time out.
1402 @retval EFI_SUCCESS The command start successfully.
1403
1404 **/
1405 EFI_STATUS
1406 EFIAPI
1407 AhciStartCommand (
1408 IN EFI_PCI_IO_PROTOCOL *PciIo,
1409 IN UINT8 Port,
1410 IN UINT8 CommandSlot,
1411 IN UINT64 Timeout
1412 )
1413 {
1414 UINT32 CmdSlotBit;
1415 EFI_STATUS Status;
1416 UINT32 PortStatus;
1417 UINT32 StartCmd;
1418 UINT32 PortTfd;
1419 UINT32 Offset;
1420 UINT32 Capability;
1421
1422 //
1423 // Collect AHCI controller information
1424 //
1425 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1426
1427 CmdSlotBit = (UINT32) (1 << CommandSlot);
1428
1429 AhciClearPortStatus (
1430 PciIo,
1431 Port
1432 );
1433
1434 Status = AhciEnableFisReceive (
1435 PciIo,
1436 Port,
1437 Timeout
1438 );
1439
1440 if (EFI_ERROR (Status)) {
1441 return Status;
1442 }
1443
1444 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1445 PortStatus = AhciReadReg (PciIo, Offset);
1446
1447 StartCmd = 0;
1448 if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
1449 StartCmd = AhciReadReg (PciIo, Offset);
1450 StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;
1451 StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;
1452 }
1453
1454 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
1455 PortTfd = AhciReadReg (PciIo, Offset);
1456
1457 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
1458 if ((Capability & BIT24) != 0) {
1459 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1460 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_CLO);
1461
1462 AhciWaitMmioSet (
1463 PciIo,
1464 Offset,
1465 EFI_AHCI_PORT_CMD_CLO,
1466 0,
1467 Timeout
1468 );
1469 }
1470 }
1471
1472 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1473 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
1474
1475 //
1476 // Setting the command
1477 //
1478 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
1479 AhciAndReg (PciIo, Offset, 0);
1480 AhciOrReg (PciIo, Offset, CmdSlotBit);
1481
1482 return EFI_SUCCESS;
1483 }
1484
1485
1486 /**
1487 Do AHCI HBA reset.
1488
1489 @param PciIo The PCI IO protocol instance.
1490 @param Timeout The timeout value of reset, uses 100ns as a unit.
1491
1492 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
1493 @retval EFI_TIMEOUT The reset operation is time out.
1494 @retval EFI_SUCCESS AHCI controller is reset successfully.
1495
1496 **/
1497 EFI_STATUS
1498 EFIAPI
1499 AhciReset (
1500 IN EFI_PCI_IO_PROTOCOL *PciIo,
1501 IN UINT64 Timeout
1502 )
1503 {
1504 UINT64 Delay;
1505 UINT32 Value;
1506
1507 //
1508 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1509 //
1510 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
1511
1512 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
1513 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
1514 }
1515
1516 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);
1517
1518 Delay = DivU64x32(Timeout, 1000) + 1;
1519
1520 do {
1521 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
1522
1523 if ((Value & EFI_AHCI_GHC_RESET) == 0) {
1524 break;
1525 }
1526
1527 //
1528 // Stall for 100 microseconds.
1529 //
1530 MicroSecondDelay(100);
1531
1532 Delay--;
1533 } while (Delay > 0);
1534
1535 if (Delay == 0) {
1536 return EFI_TIMEOUT;
1537 }
1538
1539 return EFI_SUCCESS;
1540 }
1541
1542 /**
1543 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
1544
1545 @param PciIo The PCI IO protocol instance.
1546 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1547 @param Port The number of port.
1548 @param PortMultiplier The port multiplier port number.
1549 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1550
1551 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
1552 @retval Others Fail to get return status data.
1553
1554 **/
1555 EFI_STATUS
1556 EFIAPI
1557 AhciAtaSmartReturnStatusCheck (
1558 IN EFI_PCI_IO_PROTOCOL *PciIo,
1559 IN EFI_AHCI_REGISTERS *AhciRegisters,
1560 IN UINT8 Port,
1561 IN UINT8 PortMultiplier,
1562 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1563 )
1564 {
1565 EFI_STATUS Status;
1566 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1567 UINT8 LBAMid;
1568 UINT8 LBAHigh;
1569 UINTN FisBaseAddr;
1570 UINT32 Value;
1571
1572 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1573
1574 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1575 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
1576 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1577 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1578
1579 //
1580 // Send S.M.A.R.T Read Return Status command to device
1581 //
1582 Status = AhciNonDataTransfer (
1583 PciIo,
1584 AhciRegisters,
1585 (UINT8)Port,
1586 (UINT8)PortMultiplier,
1587 NULL,
1588 0,
1589 &AtaCommandBlock,
1590 AtaStatusBlock,
1591 ATA_ATAPI_TIMEOUT,
1592 NULL
1593 );
1594
1595 if (EFI_ERROR (Status)) {
1596 REPORT_STATUS_CODE (
1597 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1598 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
1599 );
1600 return EFI_DEVICE_ERROR;
1601 }
1602
1603 REPORT_STATUS_CODE (
1604 EFI_PROGRESS_CODE,
1605 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
1606 );
1607
1608 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
1609
1610 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
1611
1612 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
1613 LBAMid = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[5];
1614 LBAHigh = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[6];
1615
1616 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
1617 //
1618 // The threshold exceeded condition is not detected by the device
1619 //
1620 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
1621 REPORT_STATUS_CODE (
1622 EFI_PROGRESS_CODE,
1623 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
1624 );
1625 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
1626 //
1627 // The threshold exceeded condition is detected by the device
1628 //
1629 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
1630 REPORT_STATUS_CODE (
1631 EFI_PROGRESS_CODE,
1632 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
1633 );
1634 }
1635 }
1636
1637 return EFI_SUCCESS;
1638 }
1639
1640 /**
1641 Enable SMART command of the disk if supported.
1642
1643 @param PciIo The PCI IO protocol instance.
1644 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1645 @param Port The number of port.
1646 @param PortMultiplier The port multiplier port number.
1647 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
1648 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1649
1650 **/
1651 VOID
1652 EFIAPI
1653 AhciAtaSmartSupport (
1654 IN EFI_PCI_IO_PROTOCOL *PciIo,
1655 IN EFI_AHCI_REGISTERS *AhciRegisters,
1656 IN UINT8 Port,
1657 IN UINT8 PortMultiplier,
1658 IN EFI_IDENTIFY_DATA *IdentifyData,
1659 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1660 )
1661 {
1662 EFI_STATUS Status;
1663 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1664
1665 //
1666 // Detect if the device supports S.M.A.R.T.
1667 //
1668 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
1669 //
1670 // S.M.A.R.T is not supported by the device
1671 //
1672 DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n",
1673 Port, PortMultiplier));
1674 REPORT_STATUS_CODE (
1675 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1676 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
1677 );
1678 } else {
1679 //
1680 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
1681 //
1682 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
1683
1684 REPORT_STATUS_CODE (
1685 EFI_PROGRESS_CODE,
1686 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
1687 );
1688
1689 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1690
1691 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1692 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
1693 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1694 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1695
1696 //
1697 // Send S.M.A.R.T Enable command to device
1698 //
1699 Status = AhciNonDataTransfer (
1700 PciIo,
1701 AhciRegisters,
1702 (UINT8)Port,
1703 (UINT8)PortMultiplier,
1704 NULL,
1705 0,
1706 &AtaCommandBlock,
1707 AtaStatusBlock,
1708 ATA_ATAPI_TIMEOUT,
1709 NULL
1710 );
1711
1712
1713 if (!EFI_ERROR (Status)) {
1714 //
1715 // Send S.M.A.R.T AutoSave command to device
1716 //
1717 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1718
1719 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1720 AtaCommandBlock.AtaFeatures = 0xD2;
1721 AtaCommandBlock.AtaSectorCount = 0xF1;
1722 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1723 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1724
1725 Status = AhciNonDataTransfer (
1726 PciIo,
1727 AhciRegisters,
1728 (UINT8)Port,
1729 (UINT8)PortMultiplier,
1730 NULL,
1731 0,
1732 &AtaCommandBlock,
1733 AtaStatusBlock,
1734 ATA_ATAPI_TIMEOUT,
1735 NULL
1736 );
1737
1738 if (!EFI_ERROR (Status)) {
1739 Status = AhciAtaSmartReturnStatusCheck (
1740 PciIo,
1741 AhciRegisters,
1742 (UINT8)Port,
1743 (UINT8)PortMultiplier,
1744 AtaStatusBlock
1745 );
1746 }
1747 }
1748 }
1749 DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
1750 Port, PortMultiplier));
1751 }
1752
1753 return ;
1754 }
1755
1756 /**
1757 Send Buffer cmd to specific device.
1758
1759 @param PciIo The PCI IO protocol instance.
1760 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1761 @param Port The number of port.
1762 @param PortMultiplier The port multiplier port number.
1763 @param Buffer The data buffer to store IDENTIFY PACKET data.
1764
1765 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1766 @retval EFI_TIMEOUT The operation is time out.
1767 @retval EFI_UNSUPPORTED The device is not ready for executing.
1768 @retval EFI_SUCCESS The cmd executes successfully.
1769
1770 **/
1771 EFI_STATUS
1772 EFIAPI
1773 AhciIdentify (
1774 IN EFI_PCI_IO_PROTOCOL *PciIo,
1775 IN EFI_AHCI_REGISTERS *AhciRegisters,
1776 IN UINT8 Port,
1777 IN UINT8 PortMultiplier,
1778 IN OUT EFI_IDENTIFY_DATA *Buffer
1779 )
1780 {
1781 EFI_STATUS Status;
1782 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1783 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1784
1785 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) {
1786 return EFI_INVALID_PARAMETER;
1787 }
1788
1789 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1790 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1791
1792 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1793 AtaCommandBlock.AtaSectorCount = 1;
1794
1795 Status = AhciPioTransfer (
1796 PciIo,
1797 AhciRegisters,
1798 Port,
1799 PortMultiplier,
1800 NULL,
1801 0,
1802 TRUE,
1803 &AtaCommandBlock,
1804 &AtaStatusBlock,
1805 Buffer,
1806 sizeof (EFI_IDENTIFY_DATA),
1807 ATA_ATAPI_TIMEOUT,
1808 NULL
1809 );
1810
1811 return Status;
1812 }
1813
1814 /**
1815 Send Buffer cmd to specific device.
1816
1817 @param PciIo The PCI IO protocol instance.
1818 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1819 @param Port The number of port.
1820 @param PortMultiplier The port multiplier port number.
1821 @param Buffer The data buffer to store IDENTIFY PACKET data.
1822
1823 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1824 @retval EFI_TIMEOUT The operation is time out.
1825 @retval EFI_UNSUPPORTED The device is not ready for executing.
1826 @retval EFI_SUCCESS The cmd executes successfully.
1827
1828 **/
1829 EFI_STATUS
1830 EFIAPI
1831 AhciIdentifyPacket (
1832 IN EFI_PCI_IO_PROTOCOL *PciIo,
1833 IN EFI_AHCI_REGISTERS *AhciRegisters,
1834 IN UINT8 Port,
1835 IN UINT8 PortMultiplier,
1836 IN OUT EFI_IDENTIFY_DATA *Buffer
1837 )
1838 {
1839 EFI_STATUS Status;
1840 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1841 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1842
1843 if (PciIo == NULL || AhciRegisters == NULL) {
1844 return EFI_INVALID_PARAMETER;
1845 }
1846
1847 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1848 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1849
1850 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
1851 AtaCommandBlock.AtaSectorCount = 1;
1852
1853 Status = AhciPioTransfer (
1854 PciIo,
1855 AhciRegisters,
1856 Port,
1857 PortMultiplier,
1858 NULL,
1859 0,
1860 TRUE,
1861 &AtaCommandBlock,
1862 &AtaStatusBlock,
1863 Buffer,
1864 sizeof (EFI_IDENTIFY_DATA),
1865 ATA_ATAPI_TIMEOUT,
1866 NULL
1867 );
1868
1869 return Status;
1870 }
1871
1872 /**
1873 Send SET FEATURE cmd on specific device.
1874
1875 @param PciIo The PCI IO protocol instance.
1876 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1877 @param Port The number of port.
1878 @param PortMultiplier The port multiplier port number.
1879 @param Feature The data to send Feature register.
1880 @param FeatureSpecificData The specific data for SET FEATURE cmd.
1881 @param Timeout The timeout value of SET FEATURE cmd, uses 100ns as a unit.
1882
1883 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1884 @retval EFI_TIMEOUT The operation is time out.
1885 @retval EFI_UNSUPPORTED The device is not ready for executing.
1886 @retval EFI_SUCCESS The cmd executes successfully.
1887
1888 **/
1889 EFI_STATUS
1890 EFIAPI
1891 AhciDeviceSetFeature (
1892 IN EFI_PCI_IO_PROTOCOL *PciIo,
1893 IN EFI_AHCI_REGISTERS *AhciRegisters,
1894 IN UINT8 Port,
1895 IN UINT8 PortMultiplier,
1896 IN UINT16 Feature,
1897 IN UINT32 FeatureSpecificData,
1898 IN UINT64 Timeout
1899 )
1900 {
1901 EFI_STATUS Status;
1902 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1903 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1904
1905 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1906 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1907
1908 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
1909 AtaCommandBlock.AtaFeatures = (UINT8) Feature;
1910 AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8);
1911 AtaCommandBlock.AtaSectorCount = (UINT8) FeatureSpecificData;
1912 AtaCommandBlock.AtaSectorNumber = (UINT8) (FeatureSpecificData >> 8);
1913 AtaCommandBlock.AtaCylinderLow = (UINT8) (FeatureSpecificData >> 16);
1914 AtaCommandBlock.AtaCylinderHigh = (UINT8) (FeatureSpecificData >> 24);
1915
1916 Status = AhciNonDataTransfer (
1917 PciIo,
1918 AhciRegisters,
1919 (UINT8)Port,
1920 (UINT8)PortMultiplier,
1921 NULL,
1922 0,
1923 &AtaCommandBlock,
1924 &AtaStatusBlock,
1925 Timeout,
1926 NULL
1927 );
1928
1929 return Status;
1930 }
1931
1932 /**
1933 This function is used to send out ATAPI commands conforms to the Packet Command
1934 with PIO Protocol.
1935
1936 @param PciIo The PCI IO protocol instance.
1937 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1938 @param Port The number of port.
1939 @param PortMultiplier The number of port multiplier.
1940 @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
1941
1942 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1943 and device sends data successfully.
1944 @retval EFI_DEVICE_ERROR the device failed to send data.
1945
1946 **/
1947 EFI_STATUS
1948 EFIAPI
1949 AhciPacketCommandExecute (
1950 IN EFI_PCI_IO_PROTOCOL *PciIo,
1951 IN EFI_AHCI_REGISTERS *AhciRegisters,
1952 IN UINT8 Port,
1953 IN UINT8 PortMultiplier,
1954 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
1955 )
1956 {
1957 EFI_STATUS Status;
1958 VOID *Buffer;
1959 UINT32 Length;
1960 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1961 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1962 BOOLEAN Read;
1963
1964 if (Packet == NULL || Packet->Cdb == NULL) {
1965 return EFI_INVALID_PARAMETER;
1966 }
1967
1968 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1969 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1970 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
1971 //
1972 // No OVL; No DMA
1973 //
1974 AtaCommandBlock.AtaFeatures = 0x00;
1975 //
1976 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1977 // determine how many data should be transferred.
1978 //
1979 AtaCommandBlock.AtaCylinderLow = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);
1980 AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);
1981
1982 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1983 Buffer = Packet->InDataBuffer;
1984 Length = Packet->InTransferLength;
1985 Read = TRUE;
1986 } else {
1987 Buffer = Packet->OutDataBuffer;
1988 Length = Packet->OutTransferLength;
1989 Read = FALSE;
1990 }
1991
1992 if (Length == 0) {
1993 Status = AhciNonDataTransfer (
1994 PciIo,
1995 AhciRegisters,
1996 Port,
1997 PortMultiplier,
1998 Packet->Cdb,
1999 Packet->CdbLength,
2000 &AtaCommandBlock,
2001 &AtaStatusBlock,
2002 Packet->Timeout,
2003 NULL
2004 );
2005 } else {
2006 Status = AhciPioTransfer (
2007 PciIo,
2008 AhciRegisters,
2009 Port,
2010 PortMultiplier,
2011 Packet->Cdb,
2012 Packet->CdbLength,
2013 Read,
2014 &AtaCommandBlock,
2015 &AtaStatusBlock,
2016 Buffer,
2017 Length,
2018 Packet->Timeout,
2019 NULL
2020 );
2021 }
2022 return Status;
2023 }
2024
2025 /**
2026 Allocate transfer-related data struct which is used at AHCI mode.
2027
2028 @param PciIo The PCI IO protocol instance.
2029 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2030
2031 **/
2032 EFI_STATUS
2033 EFIAPI
2034 AhciCreateTransferDescriptor (
2035 IN EFI_PCI_IO_PROTOCOL *PciIo,
2036 IN OUT EFI_AHCI_REGISTERS *AhciRegisters
2037 )
2038 {
2039 EFI_STATUS Status;
2040 UINTN Bytes;
2041 VOID *Buffer;
2042
2043 UINT32 Capability;
2044 UINT32 PortImplementBitMap;
2045 UINT8 MaxPortNumber;
2046 UINT8 MaxCommandSlotNumber;
2047 BOOLEAN Support64Bit;
2048 UINT64 MaxReceiveFisSize;
2049 UINT64 MaxCommandListSize;
2050 UINT64 MaxCommandTableSize;
2051 EFI_PHYSICAL_ADDRESS AhciRFisPciAddr;
2052 EFI_PHYSICAL_ADDRESS AhciCmdListPciAddr;
2053 EFI_PHYSICAL_ADDRESS AhciCommandTablePciAddr;
2054
2055 Buffer = NULL;
2056 //
2057 // Collect AHCI controller information
2058 //
2059 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2060 //
2061 // Get the number of command slots per port supported by this HBA.
2062 //
2063 MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1);
2064 Support64Bit = (BOOLEAN) (((Capability & BIT31) != 0) ? TRUE : FALSE);
2065
2066 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
2067 //
2068 // Get the highest bit of implemented ports which decides how many bytes are allocated for received FIS.
2069 //
2070 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32(PortImplementBitMap) + 1);
2071 if (MaxPortNumber == 0) {
2072 return EFI_DEVICE_ERROR;
2073 }
2074
2075 MaxReceiveFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
2076 Status = PciIo->AllocateBuffer (
2077 PciIo,
2078 AllocateAnyPages,
2079 EfiBootServicesData,
2080 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize),
2081 &Buffer,
2082 0
2083 );
2084
2085 if (EFI_ERROR (Status)) {
2086 return EFI_OUT_OF_RESOURCES;
2087 }
2088
2089 ZeroMem (Buffer, (UINTN)MaxReceiveFisSize);
2090
2091 AhciRegisters->AhciRFis = Buffer;
2092 AhciRegisters->MaxReceiveFisSize = MaxReceiveFisSize;
2093 Bytes = (UINTN)MaxReceiveFisSize;
2094
2095 Status = PciIo->Map (
2096 PciIo,
2097 EfiPciIoOperationBusMasterCommonBuffer,
2098 Buffer,
2099 &Bytes,
2100 &AhciRFisPciAddr,
2101 &AhciRegisters->MapRFis
2102 );
2103
2104 if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) {
2105 //
2106 // Map error or unable to map the whole RFis buffer into a contiguous region.
2107 //
2108 Status = EFI_OUT_OF_RESOURCES;
2109 goto Error6;
2110 }
2111
2112 if ((!Support64Bit) && (AhciRFisPciAddr > 0x100000000ULL)) {
2113 //
2114 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2115 //
2116 Status = EFI_DEVICE_ERROR;
2117 goto Error5;
2118 }
2119 AhciRegisters->AhciRFisPciAddr = (EFI_AHCI_RECEIVED_FIS *)(UINTN)AhciRFisPciAddr;
2120
2121 //
2122 // Allocate memory for command list
2123 // Note that the implementation is a single task model which only use a command list for all ports.
2124 //
2125 Buffer = NULL;
2126 MaxCommandListSize = MaxCommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST);
2127 Status = PciIo->AllocateBuffer (
2128 PciIo,
2129 AllocateAnyPages,
2130 EfiBootServicesData,
2131 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize),
2132 &Buffer,
2133 0
2134 );
2135
2136 if (EFI_ERROR (Status)) {
2137 //
2138 // Free mapped resource.
2139 //
2140 Status = EFI_OUT_OF_RESOURCES;
2141 goto Error5;
2142 }
2143
2144 ZeroMem (Buffer, (UINTN)MaxCommandListSize);
2145
2146 AhciRegisters->AhciCmdList = Buffer;
2147 AhciRegisters->MaxCommandListSize = MaxCommandListSize;
2148 Bytes = (UINTN)MaxCommandListSize;
2149
2150 Status = PciIo->Map (
2151 PciIo,
2152 EfiPciIoOperationBusMasterCommonBuffer,
2153 Buffer,
2154 &Bytes,
2155 &AhciCmdListPciAddr,
2156 &AhciRegisters->MapCmdList
2157 );
2158
2159 if (EFI_ERROR (Status) || (Bytes != MaxCommandListSize)) {
2160 //
2161 // Map error or unable to map the whole cmd list buffer into a contiguous region.
2162 //
2163 Status = EFI_OUT_OF_RESOURCES;
2164 goto Error4;
2165 }
2166
2167 if ((!Support64Bit) && (AhciCmdListPciAddr > 0x100000000ULL)) {
2168 //
2169 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2170 //
2171 Status = EFI_DEVICE_ERROR;
2172 goto Error3;
2173 }
2174 AhciRegisters->AhciCmdListPciAddr = (EFI_AHCI_COMMAND_LIST *)(UINTN)AhciCmdListPciAddr;
2175
2176 //
2177 // Allocate memory for command table
2178 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
2179 //
2180 Buffer = NULL;
2181 MaxCommandTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
2182
2183 Status = PciIo->AllocateBuffer (
2184 PciIo,
2185 AllocateAnyPages,
2186 EfiBootServicesData,
2187 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize),
2188 &Buffer,
2189 0
2190 );
2191
2192 if (EFI_ERROR (Status)) {
2193 //
2194 // Free mapped resource.
2195 //
2196 Status = EFI_OUT_OF_RESOURCES;
2197 goto Error3;
2198 }
2199
2200 ZeroMem (Buffer, (UINTN)MaxCommandTableSize);
2201
2202 AhciRegisters->AhciCommandTable = Buffer;
2203 AhciRegisters->MaxCommandTableSize = MaxCommandTableSize;
2204 Bytes = (UINTN)MaxCommandTableSize;
2205
2206 Status = PciIo->Map (
2207 PciIo,
2208 EfiPciIoOperationBusMasterCommonBuffer,
2209 Buffer,
2210 &Bytes,
2211 &AhciCommandTablePciAddr,
2212 &AhciRegisters->MapCommandTable
2213 );
2214
2215 if (EFI_ERROR (Status) || (Bytes != MaxCommandTableSize)) {
2216 //
2217 // Map error or unable to map the whole cmd list buffer into a contiguous region.
2218 //
2219 Status = EFI_OUT_OF_RESOURCES;
2220 goto Error2;
2221 }
2222
2223 if ((!Support64Bit) && (AhciCommandTablePciAddr > 0x100000000ULL)) {
2224 //
2225 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2226 //
2227 Status = EFI_DEVICE_ERROR;
2228 goto Error1;
2229 }
2230 AhciRegisters->AhciCommandTablePciAddr = (EFI_AHCI_COMMAND_TABLE *)(UINTN)AhciCommandTablePciAddr;
2231
2232 return EFI_SUCCESS;
2233 //
2234 // Map error or unable to map the whole CmdList buffer into a contiguous region.
2235 //
2236 Error1:
2237 PciIo->Unmap (
2238 PciIo,
2239 AhciRegisters->MapCommandTable
2240 );
2241 Error2:
2242 PciIo->FreeBuffer (
2243 PciIo,
2244 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize),
2245 AhciRegisters->AhciCommandTable
2246 );
2247 Error3:
2248 PciIo->Unmap (
2249 PciIo,
2250 AhciRegisters->MapCmdList
2251 );
2252 Error4:
2253 PciIo->FreeBuffer (
2254 PciIo,
2255 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize),
2256 AhciRegisters->AhciCmdList
2257 );
2258 Error5:
2259 PciIo->Unmap (
2260 PciIo,
2261 AhciRegisters->MapRFis
2262 );
2263 Error6:
2264 PciIo->FreeBuffer (
2265 PciIo,
2266 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize),
2267 AhciRegisters->AhciRFis
2268 );
2269
2270 return Status;
2271 }
2272
2273 /**
2274 Read logs from SATA device.
2275
2276 @param PciIo The PCI IO protocol instance.
2277 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2278 @param Port The number of port.
2279 @param PortMultiplier The multiplier of port.
2280 @param Buffer The data buffer to store SATA logs.
2281 @param LogNumber The address of the log.
2282 @param PageNumber The page number of the log.
2283
2284 @retval EFI_INVALID_PARAMETER PciIo, AhciRegisters or Buffer is NULL.
2285 @retval others Return status of AhciPioTransfer().
2286 **/
2287 EFI_STATUS
2288 AhciReadLogExt (
2289 IN EFI_PCI_IO_PROTOCOL *PciIo,
2290 IN EFI_AHCI_REGISTERS *AhciRegisters,
2291 IN UINT8 Port,
2292 IN UINT8 PortMultiplier,
2293 IN OUT UINT8 *Buffer,
2294 IN UINT8 LogNumber,
2295 IN UINT8 PageNumber
2296 )
2297 {
2298 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2299 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2300
2301 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) {
2302 return EFI_INVALID_PARAMETER;
2303 }
2304
2305 ///
2306 /// Read log from device
2307 ///
2308 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2309 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2310 ZeroMem (Buffer, 512);
2311
2312 AtaCommandBlock.AtaCommand = ATA_CMD_READ_LOG_EXT;
2313 AtaCommandBlock.AtaSectorCount = 1;
2314 AtaCommandBlock.AtaSectorNumber = LogNumber;
2315 AtaCommandBlock.AtaCylinderLow = PageNumber;
2316
2317 return AhciPioTransfer (
2318 PciIo,
2319 AhciRegisters,
2320 Port,
2321 PortMultiplier,
2322 NULL,
2323 0,
2324 TRUE,
2325 &AtaCommandBlock,
2326 &AtaStatusBlock,
2327 Buffer,
2328 512,
2329 ATA_ATAPI_TIMEOUT,
2330 NULL
2331 );
2332 }
2333
2334 /**
2335 Enable DEVSLP of the disk if supported.
2336
2337 @param PciIo The PCI IO protocol instance.
2338 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2339 @param Port The number of port.
2340 @param PortMultiplier The multiplier of port.
2341 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2342
2343 @retval EFI_SUCCESS The DEVSLP is enabled per policy successfully.
2344 @retval EFI_UNSUPPORTED The DEVSLP isn't supported by the controller/device and policy requires to enable it.
2345 **/
2346 EFI_STATUS
2347 AhciEnableDevSlp (
2348 IN EFI_PCI_IO_PROTOCOL *PciIo,
2349 IN EFI_AHCI_REGISTERS *AhciRegisters,
2350 IN UINT8 Port,
2351 IN UINT8 PortMultiplier,
2352 IN EFI_IDENTIFY_DATA *IdentifyData
2353 )
2354 {
2355 EFI_STATUS Status;
2356 UINT32 Offset;
2357 UINT32 Capability2;
2358 UINT8 LogData[512];
2359 DEVSLP_TIMING_VARIABLES DevSlpTiming;
2360 UINT32 PortCmd;
2361 UINT32 PortDevSlp;
2362
2363 if (mAtaAtapiPolicy->DeviceSleepEnable != 1) {
2364 return EFI_SUCCESS;
2365 }
2366
2367 //
2368 // Do not enable DevSlp if DevSlp is not supported.
2369 //
2370 Capability2 = AhciReadReg (PciIo, AHCI_CAPABILITY2_OFFSET);
2371 DEBUG ((DEBUG_INFO, "AHCI CAPABILITY2 = %08x\n", Capability2));
2372 if ((Capability2 & AHCI_CAP2_SDS) == 0) {
2373 return EFI_UNSUPPORTED;
2374 }
2375
2376 //
2377 // Do not enable DevSlp if DevSlp is not present
2378 // Do not enable DevSlp if Hot Plug or Mechanical Presence Switch is supported
2379 //
2380 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH;
2381 PortCmd = AhciReadReg (PciIo, Offset + EFI_AHCI_PORT_CMD);
2382 PortDevSlp = AhciReadReg (PciIo, Offset + AHCI_PORT_DEVSLP);
2383 DEBUG ((DEBUG_INFO, "Port CMD/DEVSLP = %08x / %08x\n", PortCmd, PortDevSlp));
2384 if (((PortDevSlp & AHCI_PORT_DEVSLP_DSP) == 0) ||
2385 ((PortCmd & (EFI_AHCI_PORT_CMD_HPCP | EFI_AHCI_PORT_CMD_MPSP)) != 0)
2386 ) {
2387 return EFI_UNSUPPORTED;
2388 }
2389
2390 //
2391 // Do not enable DevSlp if the device doesn't support DevSlp
2392 //
2393 DEBUG ((DEBUG_INFO, "IDENTIFY DEVICE: [77] = %04x, [78] = %04x, [79] = %04x\n",
2394 IdentifyData->AtaData.reserved_77,
2395 IdentifyData->AtaData.serial_ata_features_supported, IdentifyData->AtaData.serial_ata_features_enabled));
2396 if ((IdentifyData->AtaData.serial_ata_features_supported & BIT8) == 0) {
2397 DEBUG ((DEBUG_INFO, "DevSlp feature is not supported for device at port [%d] PortMultiplier [%d]!\n",
2398 Port, PortMultiplier));
2399 return EFI_UNSUPPORTED;
2400 }
2401
2402 //
2403 // Enable DevSlp when it is not enabled.
2404 //
2405 if ((IdentifyData->AtaData.serial_ata_features_enabled & BIT8) != 0) {
2406 Status = AhciDeviceSetFeature (
2407 PciIo, AhciRegisters, Port, 0, ATA_SUB_CMD_ENABLE_SATA_FEATURE, 0x09, ATA_ATAPI_TIMEOUT
2408 );
2409 DEBUG ((DEBUG_INFO, "DevSlp set feature for device at port [%d] PortMultiplier [%d] - %r\n",
2410 Port, PortMultiplier, Status));
2411 if (EFI_ERROR (Status)) {
2412 return Status;
2413 }
2414 }
2415
2416 Status = AhciReadLogExt(PciIo, AhciRegisters, Port, PortMultiplier, LogData, 0x30, 0x08);
2417
2418 //
2419 // Clear PxCMD.ST and PxDEVSLP.ADSE before updating PxDEVSLP.DITO and PxDEVSLP.MDAT.
2420 //
2421 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd & ~EFI_AHCI_PORT_CMD_ST);
2422 PortDevSlp &= ~AHCI_PORT_DEVSLP_ADSE;
2423 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2424
2425 //
2426 // Set PxDEVSLP.DETO and PxDEVSLP.MDAT to 0.
2427 //
2428 PortDevSlp &= ~AHCI_PORT_DEVSLP_DETO_MASK;
2429 PortDevSlp &= ~AHCI_PORT_DEVSLP_MDAT_MASK;
2430 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2431 DEBUG ((DEBUG_INFO, "Read Log Ext at port [%d] PortMultiplier [%d] - %r\n", Port, PortMultiplier, Status));
2432 if (EFI_ERROR (Status)) {
2433 //
2434 // Assume DEVSLP TIMING VARIABLES is not supported if the Identify Device Data log (30h, 8) fails
2435 //
2436 ZeroMem (&DevSlpTiming, sizeof (DevSlpTiming));
2437 } else {
2438 CopyMem (&DevSlpTiming, &LogData[48], sizeof (DevSlpTiming));
2439 DEBUG ((DEBUG_INFO, "DevSlpTiming: Supported(%d), Deto(%d), Madt(%d)\n",
2440 DevSlpTiming.Supported, DevSlpTiming.Deto, DevSlpTiming.Madt));
2441 }
2442
2443 //
2444 // Use 20ms as default DETO when DEVSLP TIMING VARIABLES is not supported or the DETO is 0.
2445 //
2446 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Deto == 0)) {
2447 DevSlpTiming.Deto = 20;
2448 }
2449
2450 //
2451 // Use 10ms as default MADT when DEVSLP TIMING VARIABLES is not supported or the MADT is 0.
2452 //
2453 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Madt == 0)) {
2454 DevSlpTiming.Madt = 10;
2455 }
2456
2457 PortDevSlp |= DevSlpTiming.Deto << 2;
2458 PortDevSlp |= DevSlpTiming.Madt << 10;
2459 AhciOrReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2460
2461 if (mAtaAtapiPolicy->AggressiveDeviceSleepEnable == 1) {
2462 if ((Capability2 & AHCI_CAP2_SADM) != 0) {
2463 PortDevSlp &= ~AHCI_PORT_DEVSLP_DITO_MASK;
2464 PortDevSlp |= (625 << 15);
2465 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2466
2467 PortDevSlp |= AHCI_PORT_DEVSLP_ADSE;
2468 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2469 }
2470 }
2471
2472
2473 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd);
2474
2475 DEBUG ((DEBUG_INFO, "Enabled DevSlp feature at port [%d] PortMultiplier [%d], Port CMD/DEVSLP = %08x / %08x\n",
2476 Port, PortMultiplier, PortCmd, PortDevSlp));
2477
2478 return EFI_SUCCESS;
2479 }
2480
2481 /**
2482 Spin-up disk if IDD was incomplete or PUIS feature is enabled
2483
2484 @param PciIo The PCI IO protocol instance.
2485 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2486 @param Port The number of port.
2487 @param PortMultiplier The multiplier of port.
2488 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2489
2490 **/
2491 EFI_STATUS
2492 AhciSpinUpDisk (
2493 IN EFI_PCI_IO_PROTOCOL *PciIo,
2494 IN EFI_AHCI_REGISTERS *AhciRegisters,
2495 IN UINT8 Port,
2496 IN UINT8 PortMultiplier,
2497 IN OUT EFI_IDENTIFY_DATA *IdentifyData
2498 )
2499 {
2500 EFI_STATUS Status;
2501 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2502 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2503 UINT8 Buffer[512];
2504
2505 if (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_REQUIRED_IDD_INCOMPLETE) {
2506 //
2507 // Use SET_FEATURE subcommand to spin up the device.
2508 //
2509 Status = AhciDeviceSetFeature (
2510 PciIo, AhciRegisters, Port, PortMultiplier,
2511 ATA_SUB_CMD_PUIS_SET_DEVICE_SPINUP, 0x00, ATA_SPINUP_TIMEOUT
2512 );
2513 DEBUG ((DEBUG_INFO, "CMD_PUIS_SET_DEVICE_SPINUP for device at port [%d] PortMultiplier [%d] - %r!\n",
2514 Port, PortMultiplier, Status));
2515 if (EFI_ERROR (Status)) {
2516 return Status;
2517 }
2518 } else {
2519 ASSERT (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_NOT_REQUIRED_IDD_INCOMPLETE);
2520
2521 //
2522 // Use READ_SECTORS to spin up the device if SpinUp SET FEATURE subcommand is not supported
2523 //
2524 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2525 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2526 //
2527 // Perform READ SECTORS PIO Data-In command to Read LBA 0
2528 //
2529 AtaCommandBlock.AtaCommand = ATA_CMD_READ_SECTORS;
2530 AtaCommandBlock.AtaSectorCount = 0x1;
2531
2532 Status = AhciPioTransfer (
2533 PciIo,
2534 AhciRegisters,
2535 Port,
2536 PortMultiplier,
2537 NULL,
2538 0,
2539 TRUE,
2540 &AtaCommandBlock,
2541 &AtaStatusBlock,
2542 &Buffer,
2543 sizeof (Buffer),
2544 ATA_SPINUP_TIMEOUT,
2545 NULL
2546 );
2547 DEBUG ((DEBUG_INFO, "Read LBA 0 for device at port [%d] PortMultiplier [%d] - %r!\n",
2548 Port, PortMultiplier, Status));
2549 if (EFI_ERROR (Status)) {
2550 return Status;
2551 }
2552 }
2553
2554 //
2555 // Read the complete IDENTIFY DEVICE data.
2556 //
2557 ZeroMem (IdentifyData, sizeof (*IdentifyData));
2558 Status = AhciIdentify (PciIo, AhciRegisters, Port, PortMultiplier, IdentifyData);
2559 if (EFI_ERROR (Status)) {
2560 DEBUG ((DEBUG_ERROR, "Read IDD failed for device at port [%d] PortMultiplier [%d] - %r!\n",
2561 Port, PortMultiplier, Status));
2562 return Status;
2563 }
2564
2565 DEBUG ((DEBUG_INFO, "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
2566 IdentifyData->AtaData.config, IdentifyData->AtaData.specific_config,
2567 IdentifyData->AtaData.command_set_supported_83, IdentifyData->AtaData.command_set_feature_enb_86));
2568 //
2569 // Check if IDD is incomplete
2570 //
2571 if ((IdentifyData->AtaData.config & BIT2) != 0) {
2572 return EFI_DEVICE_ERROR;
2573 }
2574
2575 return EFI_SUCCESS;
2576 }
2577
2578 /**
2579 Enable/disable/skip PUIS of the disk according to policy.
2580
2581 @param PciIo The PCI IO protocol instance.
2582 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2583 @param Port The number of port.
2584 @param PortMultiplier The multiplier of port.
2585
2586 **/
2587 EFI_STATUS
2588 AhciPuisEnable (
2589 IN EFI_PCI_IO_PROTOCOL *PciIo,
2590 IN EFI_AHCI_REGISTERS *AhciRegisters,
2591 IN UINT8 Port,
2592 IN UINT8 PortMultiplier
2593 )
2594 {
2595 EFI_STATUS Status;
2596
2597 Status = EFI_SUCCESS;
2598 if (mAtaAtapiPolicy->PuisEnable == 0) {
2599 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_DISABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2600 } else if (mAtaAtapiPolicy->PuisEnable == 1) {
2601 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_ENABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2602 }
2603 DEBUG ((DEBUG_INFO, "%a PUIS feature at port [%d] PortMultiplier [%d] - %r!\n",
2604 (mAtaAtapiPolicy->PuisEnable == 0) ? "Disable" : (
2605 (mAtaAtapiPolicy->PuisEnable == 1) ? "Enable" : "Skip"
2606 ), Port, PortMultiplier, Status));
2607 return Status;
2608 }
2609
2610 /**
2611 Initialize ATA host controller at AHCI mode.
2612
2613 The function is designed to initialize ATA host controller.
2614
2615 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2616
2617 **/
2618 EFI_STATUS
2619 EFIAPI
2620 AhciModeInitialization (
2621 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
2622 )
2623 {
2624 EFI_STATUS Status;
2625 EFI_PCI_IO_PROTOCOL *PciIo;
2626 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
2627 UINT32 Capability;
2628 UINT8 MaxPortNumber;
2629 UINT32 PortImplementBitMap;
2630
2631 EFI_AHCI_REGISTERS *AhciRegisters;
2632
2633 UINT8 Port;
2634 DATA_64 Data64;
2635 UINT32 Offset;
2636 UINT32 Data;
2637 EFI_IDENTIFY_DATA Buffer;
2638 EFI_ATA_DEVICE_TYPE DeviceType;
2639 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
2640 EFI_ATA_TRANSFER_MODE TransferMode;
2641 UINT32 PhyDetectDelay;
2642 UINT32 Value;
2643
2644 if (Instance == NULL) {
2645 return EFI_INVALID_PARAMETER;
2646 }
2647
2648 PciIo = Instance->PciIo;
2649 IdeInit = Instance->IdeControllerInit;
2650
2651 Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT);
2652
2653 if (EFI_ERROR (Status)) {
2654 return EFI_DEVICE_ERROR;
2655 }
2656
2657 //
2658 // Collect AHCI controller information
2659 //
2660 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2661
2662 //
2663 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
2664 //
2665 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
2666
2667 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
2668 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
2669 }
2670
2671 //
2672 // Enable 64-bit DMA support in the PCI layer if this controller
2673 // supports it.
2674 //
2675 if ((Capability & EFI_AHCI_CAP_S64A) != 0) {
2676 Status = PciIo->Attributes (
2677 PciIo,
2678 EfiPciIoAttributeOperationEnable,
2679 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
2680 NULL
2681 );
2682 if (EFI_ERROR (Status)) {
2683 DEBUG ((EFI_D_WARN,
2684 "AhciModeInitialization: failed to enable 64-bit DMA on 64-bit capable controller (%r)\n",
2685 Status));
2686 }
2687 }
2688
2689 //
2690 // Get the number of command slots per port supported by this HBA.
2691 //
2692 MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1);
2693
2694 //
2695 // Get the bit map of those ports exposed by this HBA.
2696 // It indicates which ports that the HBA supports are available for software to use.
2697 //
2698 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
2699
2700 AhciRegisters = &Instance->AhciRegisters;
2701 Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters);
2702
2703 if (EFI_ERROR (Status)) {
2704 return EFI_OUT_OF_RESOURCES;
2705 }
2706
2707 for (Port = 0; Port < EFI_AHCI_MAX_PORTS; Port ++) {
2708 if ((PortImplementBitMap & (((UINT32)BIT0) << Port)) != 0) {
2709 //
2710 // According to AHCI spec, MaxPortNumber should be equal or greater than the number of implemented ports.
2711 //
2712 if ((MaxPortNumber--) == 0) {
2713 //
2714 // Should never be here.
2715 //
2716 ASSERT (FALSE);
2717 return EFI_SUCCESS;
2718 }
2719
2720 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port);
2721
2722 //
2723 // Initialize FIS Base Address Register and Command List Base Address Register for use.
2724 //
2725 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFisPciAddr) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
2726 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;
2727 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2728 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;
2729 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2730
2731 Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdListPciAddr);
2732 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;
2733 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2734 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;
2735 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2736
2737 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2738 Data = AhciReadReg (PciIo, Offset);
2739 if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {
2740 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_POD);
2741 }
2742
2743 if ((Capability & EFI_AHCI_CAP_SSS) != 0) {
2744 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_SUD);
2745 }
2746
2747 //
2748 // Disable aggressive power management.
2749 //
2750 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
2751 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_INIT);
2752 //
2753 // Disable the reporting of the corresponding interrupt to system software.
2754 //
2755 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE;
2756 AhciAndReg (PciIo, Offset, 0);
2757
2758 //
2759 // Now inform the IDE Controller Init Module.
2760 //
2761 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, Port);
2762
2763 //
2764 // Enable FIS Receive DMA engine for the first D2H FIS.
2765 //
2766 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2767 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
2768
2769 //
2770 // Wait for the Phy to detect the presence of a device.
2771 //
2772 PhyDetectDelay = EFI_AHCI_BUS_PHY_DETECT_TIMEOUT;
2773 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
2774 do {
2775 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
2776 if ((Data == EFI_AHCI_PORT_SSTS_DET_PCE) || (Data == EFI_AHCI_PORT_SSTS_DET)) {
2777 break;
2778 }
2779
2780 MicroSecondDelay (1000);
2781 PhyDetectDelay--;
2782 } while (PhyDetectDelay > 0);
2783
2784 if (PhyDetectDelay == 0) {
2785 //
2786 // No device detected at this port.
2787 // Clear PxCMD.SUD for those ports at which there are no device present.
2788 //
2789 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2790 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_SUD));
2791 continue;
2792 }
2793
2794 Status = AhciWaitDeviceReady (PciIo, Port);
2795 if (EFI_ERROR (Status)) {
2796 continue;
2797 }
2798
2799 //
2800 // When the first D2H register FIS is received, the content of PxSIG register is updated.
2801 //
2802 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;
2803 Status = AhciWaitMmioSet (
2804 PciIo,
2805 Offset,
2806 0x0000FFFF,
2807 0x00000101,
2808 EFI_TIMER_PERIOD_SECONDS(16)
2809 );
2810 if (EFI_ERROR (Status)) {
2811 continue;
2812 }
2813
2814 Data = AhciReadReg (PciIo, Offset);
2815 if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATAPI_DEVICE_SIG) {
2816 Status = AhciIdentifyPacket (PciIo, AhciRegisters, Port, 0, &Buffer);
2817
2818 if (EFI_ERROR (Status)) {
2819 continue;
2820 }
2821
2822 DeviceType = EfiIdeCdrom;
2823 } else if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATA_DEVICE_SIG) {
2824 Status = AhciIdentify (PciIo, AhciRegisters, Port, 0, &Buffer);
2825
2826 if (EFI_ERROR (Status)) {
2827 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
2828 continue;
2829 }
2830
2831 DEBUG ((
2832 DEBUG_INFO, "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
2833 Buffer.AtaData.config, Buffer.AtaData.specific_config,
2834 Buffer.AtaData.command_set_supported_83, Buffer.AtaData.command_set_feature_enb_86
2835 ));
2836 if ((Buffer.AtaData.config & BIT2) != 0) {
2837 //
2838 // SpinUp disk if device reported incomplete IDENTIFY DEVICE.
2839 //
2840 Status = AhciSpinUpDisk (
2841 PciIo,
2842 AhciRegisters,
2843 Port,
2844 0,
2845 &Buffer
2846 );
2847 if (EFI_ERROR (Status)) {
2848 DEBUG ((DEBUG_ERROR, "Spin up standby device failed - %r\n", Status));
2849 continue;
2850 }
2851 }
2852
2853 DeviceType = EfiIdeHarddisk;
2854 } else {
2855 continue;
2856 }
2857 DEBUG ((DEBUG_INFO, "port [%d] port multitplier [%d] has a [%a]\n",
2858 Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk"));
2859
2860 //
2861 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2862 //
2863 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
2864 AhciAtaSmartSupport (
2865 PciIo,
2866 AhciRegisters,
2867 Port,
2868 0,
2869 &Buffer,
2870 NULL
2871 );
2872 }
2873
2874 //
2875 // Submit identify data to IDE controller init driver
2876 //
2877 IdeInit->SubmitData (IdeInit, Port, 0, &Buffer);
2878
2879 //
2880 // Now start to config ide device parameter and transfer mode.
2881 //
2882 Status = IdeInit->CalculateMode (
2883 IdeInit,
2884 Port,
2885 0,
2886 &SupportedModes
2887 );
2888 if (EFI_ERROR (Status)) {
2889 DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2890 continue;
2891 }
2892
2893 //
2894 // Set best supported PIO mode on this IDE device
2895 //
2896 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2897 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2898 } else {
2899 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2900 }
2901
2902 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
2903
2904 //
2905 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2906 // be set together. Only one DMA mode can be set to a device. If setting
2907 // DMA mode operation fails, we can continue moving on because we only use
2908 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2909 //
2910 if (SupportedModes->UdmaMode.Valid) {
2911 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2912 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
2913 } else if (SupportedModes->MultiWordDmaMode.Valid) {
2914 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2915 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
2916 }
2917
2918 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode), ATA_ATAPI_TIMEOUT);
2919 if (EFI_ERROR (Status)) {
2920 DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2921 continue;
2922 }
2923
2924 //
2925 // Found a ATA or ATAPI device, add it into the device list.
2926 //
2927 CreateNewDeviceInfo (Instance, Port, 0xFFFF, DeviceType, &Buffer);
2928 if (DeviceType == EfiIdeHarddisk) {
2929 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
2930 AhciEnableDevSlp (
2931 PciIo,
2932 AhciRegisters,
2933 Port,
2934 0,
2935 &Buffer
2936 );
2937 }
2938
2939 //
2940 // Enable/disable PUIS according to policy setting if PUIS is capable (Word[83].BIT5 is set).
2941 //
2942 if ((Buffer.AtaData.command_set_supported_83 & BIT5) != 0) {
2943 Status = AhciPuisEnable (
2944 PciIo,
2945 AhciRegisters,
2946 Port,
2947 0
2948 );
2949 if (EFI_ERROR (Status)) {
2950 DEBUG ((DEBUG_ERROR, "PUIS enable/disable failed, Status = %r\n", Status));
2951 continue;
2952 }
2953 }
2954 }
2955 }
2956
2957 return EFI_SUCCESS;
2958 }
2959