]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
MdeModulePkg/AtaAtapiPassThru: Check IS to check for command completion
[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 Checks if specified FIS has been received.
613
614 @param[in] PciIo Pointer to AHCI controller PciIo.
615 @param[in] Port SATA port index on which to check.
616 @param[in] FisType FIS type for which to check.
617
618 @retval EFI_SUCCESS FIS received.
619 @retval EFI_NOT_READY FIS not received yet.
620 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
621 **/
622 EFI_STATUS
623 AhciCheckFisReceived (
624 IN EFI_PCI_IO_PROTOCOL *PciIo,
625 IN UINT8 Port,
626 IN SATA_FIS_TYPE FisType
627 )
628 {
629 UINT32 Offset;
630 UINT32 PortInterrupt;
631 UINT32 PortTfd;
632
633 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
634 PortInterrupt = AhciReadReg (PciIo, Offset);
635 if ((PortInterrupt & EFI_AHCI_PORT_IS_ERROR_MASK) != 0) {
636 DEBUG ((DEBUG_ERROR, "AHCI: Error interrupt reported PxIS: %X\n", PortInterrupt));
637 return EFI_DEVICE_ERROR;
638 }
639 //
640 // For PIO setup FIS - According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered.
641 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from device
642 // after the transaction is finished successfully.
643 // To get better device compatibilities, we further check if the PxTFD's ERR bit is set.
644 // By this way, we can know if there is a real error happened.
645 //
646 if (((FisType == SataFisD2H) && ((PortInterrupt & EFI_AHCI_PORT_IS_DHRS) != 0)) ||
647 ((FisType == SataFisPioSetup) && (PortInterrupt & (EFI_AHCI_PORT_IS_PSS | EFI_AHCI_PORT_IS_DHRS)) != 0) ||
648 ((FisType == SataFisDmaSetup) && (PortInterrupt & (EFI_AHCI_PORT_IS_DSS | EFI_AHCI_PORT_IS_DHRS)) != 0)) {
649 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
650 PortTfd = AhciReadReg (PciIo, (UINT32) Offset);
651 if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {
652 return EFI_DEVICE_ERROR;
653 } else {
654 return EFI_SUCCESS;
655 }
656 }
657
658 return EFI_NOT_READY;
659 }
660
661 /**
662 Waits until specified FIS has been received.
663
664 @param[in] PciIo Pointer to AHCI controller PciIo.
665 @param[in] Port SATA port index on which to check.
666 @param[in] Timeout Time after which function should stop polling.
667 @param[in] FisType FIS type for which to check.
668
669 @retval EFI_SUCCESS FIS received.
670 @retval EFI_TIMEOUT FIS failed to arrive within a specified time period.
671 @retval EFI_DEVICE_ERROR AHCI controller reported an error on port.
672 **/
673 EFI_STATUS
674 AhciWaitUntilFisReceived (
675 IN EFI_PCI_IO_PROTOCOL *PciIo,
676 IN UINT8 Port,
677 IN UINT64 Timeout,
678 IN SATA_FIS_TYPE FisType
679 )
680 {
681 EFI_STATUS Status;
682 BOOLEAN InfiniteWait;
683 UINT64 Delay;
684
685 Delay = DivU64x32 (Timeout, 1000) + 1;
686 if (Timeout == 0) {
687 InfiniteWait = TRUE;
688 } else {
689 InfiniteWait = FALSE;
690 }
691
692 do {
693 Status = AhciCheckFisReceived (PciIo, Port, FisType);
694 if (Status != EFI_NOT_READY) {
695 return Status;
696 }
697 //
698 // Stall for 100 microseconds.
699 //
700 MicroSecondDelay (100);
701 Delay--;
702 } while (InfiniteWait || (Delay > 0));
703
704 return EFI_TIMEOUT;
705 }
706
707 /**
708 Start a PIO data transfer on specific port.
709
710 @param[in] PciIo The PCI IO protocol instance.
711 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
712 @param[in] Port The number of port.
713 @param[in] PortMultiplier The timeout value of stop.
714 @param[in] AtapiCommand The atapi command will be used for the
715 transfer.
716 @param[in] AtapiCommandLength The length of the atapi command.
717 @param[in] Read The transfer direction.
718 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
719 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
720 @param[in, out] MemoryAddr The pointer to the data buffer.
721 @param[in] DataCount The data count to be transferred.
722 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
723 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
724 used by non-blocking mode.
725
726 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
727 @retval EFI_TIMEOUT The operation is time out.
728 @retval EFI_UNSUPPORTED The device is not ready for transfer.
729 @retval EFI_SUCCESS The PIO data transfer executes successfully.
730
731 **/
732 EFI_STATUS
733 EFIAPI
734 AhciPioTransfer (
735 IN EFI_PCI_IO_PROTOCOL *PciIo,
736 IN EFI_AHCI_REGISTERS *AhciRegisters,
737 IN UINT8 Port,
738 IN UINT8 PortMultiplier,
739 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
740 IN UINT8 AtapiCommandLength,
741 IN BOOLEAN Read,
742 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
743 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
744 IN OUT VOID *MemoryAddr,
745 IN UINT32 DataCount,
746 IN UINT64 Timeout,
747 IN ATA_NONBLOCK_TASK *Task
748 )
749 {
750 EFI_STATUS Status;
751 EFI_PHYSICAL_ADDRESS PhyAddr;
752 VOID *Map;
753 UINTN MapLength;
754 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
755 EFI_AHCI_COMMAND_FIS CFis;
756 EFI_AHCI_COMMAND_LIST CmdList;
757 UINT32 PrdCount;
758
759 if (Read) {
760 Flag = EfiPciIoOperationBusMasterWrite;
761 } else {
762 Flag = EfiPciIoOperationBusMasterRead;
763 }
764
765 //
766 // construct command list and command table with pci bus address
767 //
768 MapLength = DataCount;
769 Status = PciIo->Map (
770 PciIo,
771 Flag,
772 MemoryAddr,
773 &MapLength,
774 &PhyAddr,
775 &Map
776 );
777
778 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
779 return EFI_BAD_BUFFER_SIZE;
780 }
781
782 //
783 // Package read needed
784 //
785 AhciBuildCommandFis (&CFis, AtaCommandBlock);
786
787 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
788
789 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
790 CmdList.AhciCmdW = Read ? 0 : 1;
791
792 AhciBuildCommand (
793 PciIo,
794 AhciRegisters,
795 Port,
796 PortMultiplier,
797 &CFis,
798 &CmdList,
799 AtapiCommand,
800 AtapiCommandLength,
801 0,
802 (VOID *)(UINTN)PhyAddr,
803 DataCount
804 );
805
806 Status = AhciStartCommand (
807 PciIo,
808 Port,
809 0,
810 Timeout
811 );
812 if (EFI_ERROR (Status)) {
813 goto Exit;
814 }
815
816 if (Read && (AtapiCommand == 0)) {
817 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisPioSetup);
818 if (Status == EFI_SUCCESS) {
819 PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
820 if (PrdCount == DataCount) {
821 Status = EFI_SUCCESS;
822 } else {
823 Status = EFI_DEVICE_ERROR;
824 }
825 }
826 } else {
827 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
828 }
829
830 Exit:
831 AhciStopCommand (
832 PciIo,
833 Port,
834 Timeout
835 );
836
837 AhciDisableFisReceive (
838 PciIo,
839 Port,
840 Timeout
841 );
842
843 PciIo->Unmap (
844 PciIo,
845 Map
846 );
847
848 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
849
850 return Status;
851 }
852
853 /**
854 Start a DMA data transfer on specific port
855
856 @param[in] Instance The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.
857 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
858 @param[in] Port The number of port.
859 @param[in] PortMultiplier The timeout value of stop.
860 @param[in] AtapiCommand The atapi command will be used for the
861 transfer.
862 @param[in] AtapiCommandLength The length of the atapi command.
863 @param[in] Read The transfer direction.
864 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
865 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
866 @param[in, out] MemoryAddr The pointer to the data buffer.
867 @param[in] DataCount The data count to be transferred.
868 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
869 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
870 used by non-blocking mode.
871
872 @retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
873 @retval EFI_TIMEOUT The operation is time out.
874 @retval EFI_UNSUPPORTED The device is not ready for transfer.
875 @retval EFI_SUCCESS The DMA data transfer executes successfully.
876
877 **/
878 EFI_STATUS
879 EFIAPI
880 AhciDmaTransfer (
881 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance,
882 IN EFI_AHCI_REGISTERS *AhciRegisters,
883 IN UINT8 Port,
884 IN UINT8 PortMultiplier,
885 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
886 IN UINT8 AtapiCommandLength,
887 IN BOOLEAN Read,
888 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
889 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
890 IN OUT VOID *MemoryAddr,
891 IN UINT32 DataCount,
892 IN UINT64 Timeout,
893 IN ATA_NONBLOCK_TASK *Task
894 )
895 {
896 EFI_STATUS Status;
897 EFI_PHYSICAL_ADDRESS PhyAddr;
898 VOID *Map;
899 UINTN MapLength;
900 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
901 EFI_AHCI_COMMAND_FIS CFis;
902 EFI_AHCI_COMMAND_LIST CmdList;
903
904 EFI_PCI_IO_PROTOCOL *PciIo;
905 EFI_TPL OldTpl;
906
907 Map = NULL;
908 PciIo = Instance->PciIo;
909
910 if (PciIo == NULL) {
911 return EFI_INVALID_PARAMETER;
912 }
913
914 //
915 // Before starting the Blocking BlockIO operation, push to finish all non-blocking
916 // BlockIO tasks.
917 // Delay 100us to simulate the blocking time out checking.
918 //
919 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
920 while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {
921 AsyncNonBlockingTransferRoutine (NULL, Instance);
922 //
923 // Stall for 100us.
924 //
925 MicroSecondDelay (100);
926 }
927 gBS->RestoreTPL (OldTpl);
928
929 if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) {
930 //
931 // Mark the Task to indicate that it has been started.
932 //
933 if (Task != NULL) {
934 Task->IsStart = TRUE;
935 }
936 if (Read) {
937 Flag = EfiPciIoOperationBusMasterWrite;
938 } else {
939 Flag = EfiPciIoOperationBusMasterRead;
940 }
941
942 //
943 // Construct command list and command table with pci bus address.
944 //
945 MapLength = DataCount;
946 Status = PciIo->Map (
947 PciIo,
948 Flag,
949 MemoryAddr,
950 &MapLength,
951 &PhyAddr,
952 &Map
953 );
954
955 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
956 return EFI_BAD_BUFFER_SIZE;
957 }
958
959 if (Task != NULL) {
960 Task->Map = Map;
961 }
962 //
963 // Package read needed
964 //
965 AhciBuildCommandFis (&CFis, AtaCommandBlock);
966
967 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
968
969 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
970 CmdList.AhciCmdW = Read ? 0 : 1;
971
972 AhciBuildCommand (
973 PciIo,
974 AhciRegisters,
975 Port,
976 PortMultiplier,
977 &CFis,
978 &CmdList,
979 AtapiCommand,
980 AtapiCommandLength,
981 0,
982 (VOID *)(UINTN)PhyAddr,
983 DataCount
984 );
985
986 Status = AhciStartCommand (
987 PciIo,
988 Port,
989 0,
990 Timeout
991 );
992 if (EFI_ERROR (Status)) {
993 goto Exit;
994 }
995 }
996
997 if (Task != NULL) {
998 Status = AhciCheckFisReceived (PciIo, Port, SataFisD2H);
999 if (Status == EFI_NOT_READY) {
1000 if (!Task->InfiniteWait && Task->RetryTimes == 0) {
1001 Status = EFI_TIMEOUT;
1002 } else {
1003 Task->RetryTimes--;
1004 }
1005 }
1006 } else {
1007 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1008 }
1009
1010 Exit:
1011 //
1012 // For Blocking mode, the command should be stopped, the Fis should be disabled
1013 // and the PciIo should be unmapped.
1014 // For non-blocking mode, only when a error is happened (if the return status is
1015 // EFI_NOT_READY that means the command doesn't finished, try again.), first do the
1016 // context cleanup, then set the packet's Asb status.
1017 //
1018 if (Task == NULL ||
1019 ((Task != NULL) && (Status != EFI_NOT_READY))
1020 ) {
1021 AhciStopCommand (
1022 PciIo,
1023 Port,
1024 Timeout
1025 );
1026
1027 AhciDisableFisReceive (
1028 PciIo,
1029 Port,
1030 Timeout
1031 );
1032
1033 PciIo->Unmap (
1034 PciIo,
1035 (Task != NULL) ? Task->Map : Map
1036 );
1037
1038 if (Task != NULL) {
1039 Task->Packet->Asb->AtaStatus = 0x01;
1040 }
1041 }
1042
1043 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1044 return Status;
1045 }
1046
1047 /**
1048 Start a non data transfer on specific port.
1049
1050 @param[in] PciIo The PCI IO protocol instance.
1051 @param[in] AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1052 @param[in] Port The number of port.
1053 @param[in] PortMultiplier The timeout value of stop.
1054 @param[in] AtapiCommand The atapi command will be used for the
1055 transfer.
1056 @param[in] AtapiCommandLength The length of the atapi command.
1057 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
1058 @param[in, out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
1059 @param[in] Timeout The timeout value of non data transfer, uses 100ns as a unit.
1060 @param[in] Task Optional. Pointer to the ATA_NONBLOCK_TASK
1061 used by non-blocking mode.
1062
1063 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
1064 @retval EFI_TIMEOUT The operation is time out.
1065 @retval EFI_UNSUPPORTED The device is not ready for transfer.
1066 @retval EFI_SUCCESS The non data transfer executes successfully.
1067
1068 **/
1069 EFI_STATUS
1070 EFIAPI
1071 AhciNonDataTransfer (
1072 IN EFI_PCI_IO_PROTOCOL *PciIo,
1073 IN EFI_AHCI_REGISTERS *AhciRegisters,
1074 IN UINT8 Port,
1075 IN UINT8 PortMultiplier,
1076 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
1077 IN UINT8 AtapiCommandLength,
1078 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
1079 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
1080 IN UINT64 Timeout,
1081 IN ATA_NONBLOCK_TASK *Task
1082 )
1083 {
1084 EFI_STATUS Status;
1085 EFI_AHCI_COMMAND_FIS CFis;
1086 EFI_AHCI_COMMAND_LIST CmdList;
1087
1088 //
1089 // Package read needed
1090 //
1091 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1092
1093 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1094
1095 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1096
1097 AhciBuildCommand (
1098 PciIo,
1099 AhciRegisters,
1100 Port,
1101 PortMultiplier,
1102 &CFis,
1103 &CmdList,
1104 AtapiCommand,
1105 AtapiCommandLength,
1106 0,
1107 NULL,
1108 0
1109 );
1110
1111 Status = AhciStartCommand (
1112 PciIo,
1113 Port,
1114 0,
1115 Timeout
1116 );
1117 if (EFI_ERROR (Status)) {
1118 goto Exit;
1119 }
1120
1121 Status = AhciWaitUntilFisReceived (PciIo, Port, Timeout, SataFisD2H);
1122
1123 Exit:
1124 AhciStopCommand (
1125 PciIo,
1126 Port,
1127 Timeout
1128 );
1129
1130 AhciDisableFisReceive (
1131 PciIo,
1132 Port,
1133 Timeout
1134 );
1135
1136 AhciDumpPortStatus (PciIo, AhciRegisters, Port, AtaStatusBlock);
1137
1138 return Status;
1139 }
1140
1141 /**
1142 Stop command running for giving port
1143
1144 @param PciIo The PCI IO protocol instance.
1145 @param Port The number of port.
1146 @param Timeout The timeout value of stop, uses 100ns as a unit.
1147
1148 @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
1149 @retval EFI_TIMEOUT The operation is time out.
1150 @retval EFI_SUCCESS The command stop successfully.
1151
1152 **/
1153 EFI_STATUS
1154 EFIAPI
1155 AhciStopCommand (
1156 IN EFI_PCI_IO_PROTOCOL *PciIo,
1157 IN UINT8 Port,
1158 IN UINT64 Timeout
1159 )
1160 {
1161 UINT32 Offset;
1162 UINT32 Data;
1163
1164 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1165 Data = AhciReadReg (PciIo, Offset);
1166
1167 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) {
1168 return EFI_SUCCESS;
1169 }
1170
1171 if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
1172 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));
1173 }
1174
1175 return AhciWaitMmioSet (
1176 PciIo,
1177 Offset,
1178 EFI_AHCI_PORT_CMD_CR,
1179 0,
1180 Timeout
1181 );
1182 }
1183
1184 /**
1185 Start command for give slot on specific port.
1186
1187 @param PciIo The PCI IO protocol instance.
1188 @param Port The number of port.
1189 @param CommandSlot The number of Command Slot.
1190 @param Timeout The timeout value of start, uses 100ns as a unit.
1191
1192 @retval EFI_DEVICE_ERROR The command start unsuccessfully.
1193 @retval EFI_TIMEOUT The operation is time out.
1194 @retval EFI_SUCCESS The command start successfully.
1195
1196 **/
1197 EFI_STATUS
1198 EFIAPI
1199 AhciStartCommand (
1200 IN EFI_PCI_IO_PROTOCOL *PciIo,
1201 IN UINT8 Port,
1202 IN UINT8 CommandSlot,
1203 IN UINT64 Timeout
1204 )
1205 {
1206 UINT32 CmdSlotBit;
1207 EFI_STATUS Status;
1208 UINT32 PortStatus;
1209 UINT32 StartCmd;
1210 UINT32 PortTfd;
1211 UINT32 Offset;
1212 UINT32 Capability;
1213
1214 //
1215 // Collect AHCI controller information
1216 //
1217 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1218
1219 CmdSlotBit = (UINT32) (1 << CommandSlot);
1220
1221 AhciClearPortStatus (
1222 PciIo,
1223 Port
1224 );
1225
1226 Status = AhciEnableFisReceive (
1227 PciIo,
1228 Port,
1229 Timeout
1230 );
1231
1232 if (EFI_ERROR (Status)) {
1233 return Status;
1234 }
1235
1236 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1237 PortStatus = AhciReadReg (PciIo, Offset);
1238
1239 StartCmd = 0;
1240 if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
1241 StartCmd = AhciReadReg (PciIo, Offset);
1242 StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;
1243 StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;
1244 }
1245
1246 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
1247 PortTfd = AhciReadReg (PciIo, Offset);
1248
1249 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
1250 if ((Capability & BIT24) != 0) {
1251 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1252 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_CLO);
1253
1254 AhciWaitMmioSet (
1255 PciIo,
1256 Offset,
1257 EFI_AHCI_PORT_CMD_CLO,
1258 0,
1259 Timeout
1260 );
1261 }
1262 }
1263
1264 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1265 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
1266
1267 //
1268 // Setting the command
1269 //
1270 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
1271 AhciAndReg (PciIo, Offset, 0);
1272 AhciOrReg (PciIo, Offset, CmdSlotBit);
1273
1274 return EFI_SUCCESS;
1275 }
1276
1277
1278 /**
1279 Do AHCI HBA reset.
1280
1281 @param PciIo The PCI IO protocol instance.
1282 @param Timeout The timeout value of reset, uses 100ns as a unit.
1283
1284 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
1285 @retval EFI_TIMEOUT The reset operation is time out.
1286 @retval EFI_SUCCESS AHCI controller is reset successfully.
1287
1288 **/
1289 EFI_STATUS
1290 EFIAPI
1291 AhciReset (
1292 IN EFI_PCI_IO_PROTOCOL *PciIo,
1293 IN UINT64 Timeout
1294 )
1295 {
1296 UINT64 Delay;
1297 UINT32 Value;
1298
1299 //
1300 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1301 //
1302 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
1303
1304 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
1305 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
1306 }
1307
1308 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);
1309
1310 Delay = DivU64x32(Timeout, 1000) + 1;
1311
1312 do {
1313 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
1314
1315 if ((Value & EFI_AHCI_GHC_RESET) == 0) {
1316 break;
1317 }
1318
1319 //
1320 // Stall for 100 microseconds.
1321 //
1322 MicroSecondDelay(100);
1323
1324 Delay--;
1325 } while (Delay > 0);
1326
1327 if (Delay == 0) {
1328 return EFI_TIMEOUT;
1329 }
1330
1331 return EFI_SUCCESS;
1332 }
1333
1334 /**
1335 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
1336
1337 @param PciIo The PCI IO protocol instance.
1338 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1339 @param Port The number of port.
1340 @param PortMultiplier The port multiplier port number.
1341 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1342
1343 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
1344 @retval Others Fail to get return status data.
1345
1346 **/
1347 EFI_STATUS
1348 EFIAPI
1349 AhciAtaSmartReturnStatusCheck (
1350 IN EFI_PCI_IO_PROTOCOL *PciIo,
1351 IN EFI_AHCI_REGISTERS *AhciRegisters,
1352 IN UINT8 Port,
1353 IN UINT8 PortMultiplier,
1354 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1355 )
1356 {
1357 EFI_STATUS Status;
1358 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1359 UINT8 LBAMid;
1360 UINT8 LBAHigh;
1361 UINTN FisBaseAddr;
1362 UINT32 Value;
1363
1364 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1365
1366 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1367 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
1368 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1369 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1370
1371 //
1372 // Send S.M.A.R.T Read Return Status command to device
1373 //
1374 Status = AhciNonDataTransfer (
1375 PciIo,
1376 AhciRegisters,
1377 (UINT8)Port,
1378 (UINT8)PortMultiplier,
1379 NULL,
1380 0,
1381 &AtaCommandBlock,
1382 AtaStatusBlock,
1383 ATA_ATAPI_TIMEOUT,
1384 NULL
1385 );
1386
1387 if (EFI_ERROR (Status)) {
1388 REPORT_STATUS_CODE (
1389 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1390 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
1391 );
1392 return EFI_DEVICE_ERROR;
1393 }
1394
1395 REPORT_STATUS_CODE (
1396 EFI_PROGRESS_CODE,
1397 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
1398 );
1399
1400 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
1401
1402 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
1403
1404 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
1405 LBAMid = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[5];
1406 LBAHigh = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[6];
1407
1408 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
1409 //
1410 // The threshold exceeded condition is not detected by the device
1411 //
1412 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
1413 REPORT_STATUS_CODE (
1414 EFI_PROGRESS_CODE,
1415 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
1416 );
1417 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
1418 //
1419 // The threshold exceeded condition is detected by the device
1420 //
1421 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
1422 REPORT_STATUS_CODE (
1423 EFI_PROGRESS_CODE,
1424 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
1425 );
1426 }
1427 }
1428
1429 return EFI_SUCCESS;
1430 }
1431
1432 /**
1433 Enable SMART command of the disk if supported.
1434
1435 @param PciIo The PCI IO protocol instance.
1436 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1437 @param Port The number of port.
1438 @param PortMultiplier The port multiplier port number.
1439 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
1440 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1441
1442 **/
1443 VOID
1444 EFIAPI
1445 AhciAtaSmartSupport (
1446 IN EFI_PCI_IO_PROTOCOL *PciIo,
1447 IN EFI_AHCI_REGISTERS *AhciRegisters,
1448 IN UINT8 Port,
1449 IN UINT8 PortMultiplier,
1450 IN EFI_IDENTIFY_DATA *IdentifyData,
1451 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1452 )
1453 {
1454 EFI_STATUS Status;
1455 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1456
1457 //
1458 // Detect if the device supports S.M.A.R.T.
1459 //
1460 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
1461 //
1462 // S.M.A.R.T is not supported by the device
1463 //
1464 DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n",
1465 Port, PortMultiplier));
1466 REPORT_STATUS_CODE (
1467 EFI_ERROR_CODE | EFI_ERROR_MINOR,
1468 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
1469 );
1470 } else {
1471 //
1472 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
1473 //
1474 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
1475
1476 REPORT_STATUS_CODE (
1477 EFI_PROGRESS_CODE,
1478 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)
1479 );
1480
1481 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1482
1483 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1484 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
1485 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1486 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1487
1488 //
1489 // Send S.M.A.R.T Enable command to device
1490 //
1491 Status = AhciNonDataTransfer (
1492 PciIo,
1493 AhciRegisters,
1494 (UINT8)Port,
1495 (UINT8)PortMultiplier,
1496 NULL,
1497 0,
1498 &AtaCommandBlock,
1499 AtaStatusBlock,
1500 ATA_ATAPI_TIMEOUT,
1501 NULL
1502 );
1503
1504
1505 if (!EFI_ERROR (Status)) {
1506 //
1507 // Send S.M.A.R.T AutoSave command to device
1508 //
1509 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1510
1511 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1512 AtaCommandBlock.AtaFeatures = 0xD2;
1513 AtaCommandBlock.AtaSectorCount = 0xF1;
1514 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1515 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1516
1517 Status = AhciNonDataTransfer (
1518 PciIo,
1519 AhciRegisters,
1520 (UINT8)Port,
1521 (UINT8)PortMultiplier,
1522 NULL,
1523 0,
1524 &AtaCommandBlock,
1525 AtaStatusBlock,
1526 ATA_ATAPI_TIMEOUT,
1527 NULL
1528 );
1529
1530 if (!EFI_ERROR (Status)) {
1531 Status = AhciAtaSmartReturnStatusCheck (
1532 PciIo,
1533 AhciRegisters,
1534 (UINT8)Port,
1535 (UINT8)PortMultiplier,
1536 AtaStatusBlock
1537 );
1538 }
1539 }
1540 }
1541 DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
1542 Port, PortMultiplier));
1543 }
1544
1545 return ;
1546 }
1547
1548 /**
1549 Send Buffer cmd to specific device.
1550
1551 @param PciIo The PCI IO protocol instance.
1552 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1553 @param Port The number of port.
1554 @param PortMultiplier The port multiplier port number.
1555 @param Buffer The data buffer to store IDENTIFY PACKET data.
1556
1557 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1558 @retval EFI_TIMEOUT The operation is time out.
1559 @retval EFI_UNSUPPORTED The device is not ready for executing.
1560 @retval EFI_SUCCESS The cmd executes successfully.
1561
1562 **/
1563 EFI_STATUS
1564 EFIAPI
1565 AhciIdentify (
1566 IN EFI_PCI_IO_PROTOCOL *PciIo,
1567 IN EFI_AHCI_REGISTERS *AhciRegisters,
1568 IN UINT8 Port,
1569 IN UINT8 PortMultiplier,
1570 IN OUT EFI_IDENTIFY_DATA *Buffer
1571 )
1572 {
1573 EFI_STATUS Status;
1574 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1575 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1576
1577 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) {
1578 return EFI_INVALID_PARAMETER;
1579 }
1580
1581 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1582 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1583
1584 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1585 AtaCommandBlock.AtaSectorCount = 1;
1586
1587 Status = AhciPioTransfer (
1588 PciIo,
1589 AhciRegisters,
1590 Port,
1591 PortMultiplier,
1592 NULL,
1593 0,
1594 TRUE,
1595 &AtaCommandBlock,
1596 &AtaStatusBlock,
1597 Buffer,
1598 sizeof (EFI_IDENTIFY_DATA),
1599 ATA_ATAPI_TIMEOUT,
1600 NULL
1601 );
1602
1603 return Status;
1604 }
1605
1606 /**
1607 Send Buffer cmd to specific device.
1608
1609 @param PciIo The PCI IO protocol instance.
1610 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1611 @param Port The number of port.
1612 @param PortMultiplier The port multiplier port number.
1613 @param Buffer The data buffer to store IDENTIFY PACKET data.
1614
1615 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1616 @retval EFI_TIMEOUT The operation is time out.
1617 @retval EFI_UNSUPPORTED The device is not ready for executing.
1618 @retval EFI_SUCCESS The cmd executes successfully.
1619
1620 **/
1621 EFI_STATUS
1622 EFIAPI
1623 AhciIdentifyPacket (
1624 IN EFI_PCI_IO_PROTOCOL *PciIo,
1625 IN EFI_AHCI_REGISTERS *AhciRegisters,
1626 IN UINT8 Port,
1627 IN UINT8 PortMultiplier,
1628 IN OUT EFI_IDENTIFY_DATA *Buffer
1629 )
1630 {
1631 EFI_STATUS Status;
1632 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1633 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1634
1635 if (PciIo == NULL || AhciRegisters == NULL) {
1636 return EFI_INVALID_PARAMETER;
1637 }
1638
1639 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1640 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1641
1642 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
1643 AtaCommandBlock.AtaSectorCount = 1;
1644
1645 Status = AhciPioTransfer (
1646 PciIo,
1647 AhciRegisters,
1648 Port,
1649 PortMultiplier,
1650 NULL,
1651 0,
1652 TRUE,
1653 &AtaCommandBlock,
1654 &AtaStatusBlock,
1655 Buffer,
1656 sizeof (EFI_IDENTIFY_DATA),
1657 ATA_ATAPI_TIMEOUT,
1658 NULL
1659 );
1660
1661 return Status;
1662 }
1663
1664 /**
1665 Send SET FEATURE cmd on specific device.
1666
1667 @param PciIo The PCI IO protocol instance.
1668 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1669 @param Port The number of port.
1670 @param PortMultiplier The port multiplier port number.
1671 @param Feature The data to send Feature register.
1672 @param FeatureSpecificData The specific data for SET FEATURE cmd.
1673 @param Timeout The timeout value of SET FEATURE cmd, uses 100ns as a unit.
1674
1675 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1676 @retval EFI_TIMEOUT The operation is time out.
1677 @retval EFI_UNSUPPORTED The device is not ready for executing.
1678 @retval EFI_SUCCESS The cmd executes successfully.
1679
1680 **/
1681 EFI_STATUS
1682 EFIAPI
1683 AhciDeviceSetFeature (
1684 IN EFI_PCI_IO_PROTOCOL *PciIo,
1685 IN EFI_AHCI_REGISTERS *AhciRegisters,
1686 IN UINT8 Port,
1687 IN UINT8 PortMultiplier,
1688 IN UINT16 Feature,
1689 IN UINT32 FeatureSpecificData,
1690 IN UINT64 Timeout
1691 )
1692 {
1693 EFI_STATUS Status;
1694 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1695 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1696
1697 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1698 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1699
1700 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
1701 AtaCommandBlock.AtaFeatures = (UINT8) Feature;
1702 AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8);
1703 AtaCommandBlock.AtaSectorCount = (UINT8) FeatureSpecificData;
1704 AtaCommandBlock.AtaSectorNumber = (UINT8) (FeatureSpecificData >> 8);
1705 AtaCommandBlock.AtaCylinderLow = (UINT8) (FeatureSpecificData >> 16);
1706 AtaCommandBlock.AtaCylinderHigh = (UINT8) (FeatureSpecificData >> 24);
1707
1708 Status = AhciNonDataTransfer (
1709 PciIo,
1710 AhciRegisters,
1711 (UINT8)Port,
1712 (UINT8)PortMultiplier,
1713 NULL,
1714 0,
1715 &AtaCommandBlock,
1716 &AtaStatusBlock,
1717 Timeout,
1718 NULL
1719 );
1720
1721 return Status;
1722 }
1723
1724 /**
1725 This function is used to send out ATAPI commands conforms to the Packet Command
1726 with PIO Protocol.
1727
1728 @param PciIo The PCI IO protocol instance.
1729 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1730 @param Port The number of port.
1731 @param PortMultiplier The number of port multiplier.
1732 @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
1733
1734 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1735 and device sends data successfully.
1736 @retval EFI_DEVICE_ERROR the device failed to send data.
1737
1738 **/
1739 EFI_STATUS
1740 EFIAPI
1741 AhciPacketCommandExecute (
1742 IN EFI_PCI_IO_PROTOCOL *PciIo,
1743 IN EFI_AHCI_REGISTERS *AhciRegisters,
1744 IN UINT8 Port,
1745 IN UINT8 PortMultiplier,
1746 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
1747 )
1748 {
1749 EFI_STATUS Status;
1750 VOID *Buffer;
1751 UINT32 Length;
1752 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1753 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1754 BOOLEAN Read;
1755
1756 if (Packet == NULL || Packet->Cdb == NULL) {
1757 return EFI_INVALID_PARAMETER;
1758 }
1759
1760 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1761 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1762 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
1763 //
1764 // No OVL; No DMA
1765 //
1766 AtaCommandBlock.AtaFeatures = 0x00;
1767 //
1768 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1769 // determine how many data should be transferred.
1770 //
1771 AtaCommandBlock.AtaCylinderLow = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);
1772 AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);
1773
1774 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1775 Buffer = Packet->InDataBuffer;
1776 Length = Packet->InTransferLength;
1777 Read = TRUE;
1778 } else {
1779 Buffer = Packet->OutDataBuffer;
1780 Length = Packet->OutTransferLength;
1781 Read = FALSE;
1782 }
1783
1784 if (Length == 0) {
1785 Status = AhciNonDataTransfer (
1786 PciIo,
1787 AhciRegisters,
1788 Port,
1789 PortMultiplier,
1790 Packet->Cdb,
1791 Packet->CdbLength,
1792 &AtaCommandBlock,
1793 &AtaStatusBlock,
1794 Packet->Timeout,
1795 NULL
1796 );
1797 } else {
1798 Status = AhciPioTransfer (
1799 PciIo,
1800 AhciRegisters,
1801 Port,
1802 PortMultiplier,
1803 Packet->Cdb,
1804 Packet->CdbLength,
1805 Read,
1806 &AtaCommandBlock,
1807 &AtaStatusBlock,
1808 Buffer,
1809 Length,
1810 Packet->Timeout,
1811 NULL
1812 );
1813 }
1814 return Status;
1815 }
1816
1817 /**
1818 Allocate transfer-related data struct which is used at AHCI mode.
1819
1820 @param PciIo The PCI IO protocol instance.
1821 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1822
1823 **/
1824 EFI_STATUS
1825 EFIAPI
1826 AhciCreateTransferDescriptor (
1827 IN EFI_PCI_IO_PROTOCOL *PciIo,
1828 IN OUT EFI_AHCI_REGISTERS *AhciRegisters
1829 )
1830 {
1831 EFI_STATUS Status;
1832 UINTN Bytes;
1833 VOID *Buffer;
1834
1835 UINT32 Capability;
1836 UINT32 PortImplementBitMap;
1837 UINT8 MaxPortNumber;
1838 UINT8 MaxCommandSlotNumber;
1839 BOOLEAN Support64Bit;
1840 UINT64 MaxReceiveFisSize;
1841 UINT64 MaxCommandListSize;
1842 UINT64 MaxCommandTableSize;
1843 EFI_PHYSICAL_ADDRESS AhciRFisPciAddr;
1844 EFI_PHYSICAL_ADDRESS AhciCmdListPciAddr;
1845 EFI_PHYSICAL_ADDRESS AhciCommandTablePciAddr;
1846
1847 Buffer = NULL;
1848 //
1849 // Collect AHCI controller information
1850 //
1851 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1852 //
1853 // Get the number of command slots per port supported by this HBA.
1854 //
1855 MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1);
1856 Support64Bit = (BOOLEAN) (((Capability & BIT31) != 0) ? TRUE : FALSE);
1857
1858 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
1859 //
1860 // Get the highest bit of implemented ports which decides how many bytes are allocated for received FIS.
1861 //
1862 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32(PortImplementBitMap) + 1);
1863 if (MaxPortNumber == 0) {
1864 return EFI_DEVICE_ERROR;
1865 }
1866
1867 MaxReceiveFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
1868 Status = PciIo->AllocateBuffer (
1869 PciIo,
1870 AllocateAnyPages,
1871 EfiBootServicesData,
1872 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize),
1873 &Buffer,
1874 0
1875 );
1876
1877 if (EFI_ERROR (Status)) {
1878 return EFI_OUT_OF_RESOURCES;
1879 }
1880
1881 ZeroMem (Buffer, (UINTN)MaxReceiveFisSize);
1882
1883 AhciRegisters->AhciRFis = Buffer;
1884 AhciRegisters->MaxReceiveFisSize = MaxReceiveFisSize;
1885 Bytes = (UINTN)MaxReceiveFisSize;
1886
1887 Status = PciIo->Map (
1888 PciIo,
1889 EfiPciIoOperationBusMasterCommonBuffer,
1890 Buffer,
1891 &Bytes,
1892 &AhciRFisPciAddr,
1893 &AhciRegisters->MapRFis
1894 );
1895
1896 if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) {
1897 //
1898 // Map error or unable to map the whole RFis buffer into a contiguous region.
1899 //
1900 Status = EFI_OUT_OF_RESOURCES;
1901 goto Error6;
1902 }
1903
1904 if ((!Support64Bit) && (AhciRFisPciAddr > 0x100000000ULL)) {
1905 //
1906 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
1907 //
1908 Status = EFI_DEVICE_ERROR;
1909 goto Error5;
1910 }
1911 AhciRegisters->AhciRFisPciAddr = (EFI_AHCI_RECEIVED_FIS *)(UINTN)AhciRFisPciAddr;
1912
1913 //
1914 // Allocate memory for command list
1915 // Note that the implementation is a single task model which only use a command list for all ports.
1916 //
1917 Buffer = NULL;
1918 MaxCommandListSize = MaxCommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST);
1919 Status = PciIo->AllocateBuffer (
1920 PciIo,
1921 AllocateAnyPages,
1922 EfiBootServicesData,
1923 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize),
1924 &Buffer,
1925 0
1926 );
1927
1928 if (EFI_ERROR (Status)) {
1929 //
1930 // Free mapped resource.
1931 //
1932 Status = EFI_OUT_OF_RESOURCES;
1933 goto Error5;
1934 }
1935
1936 ZeroMem (Buffer, (UINTN)MaxCommandListSize);
1937
1938 AhciRegisters->AhciCmdList = Buffer;
1939 AhciRegisters->MaxCommandListSize = MaxCommandListSize;
1940 Bytes = (UINTN)MaxCommandListSize;
1941
1942 Status = PciIo->Map (
1943 PciIo,
1944 EfiPciIoOperationBusMasterCommonBuffer,
1945 Buffer,
1946 &Bytes,
1947 &AhciCmdListPciAddr,
1948 &AhciRegisters->MapCmdList
1949 );
1950
1951 if (EFI_ERROR (Status) || (Bytes != MaxCommandListSize)) {
1952 //
1953 // Map error or unable to map the whole cmd list buffer into a contiguous region.
1954 //
1955 Status = EFI_OUT_OF_RESOURCES;
1956 goto Error4;
1957 }
1958
1959 if ((!Support64Bit) && (AhciCmdListPciAddr > 0x100000000ULL)) {
1960 //
1961 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
1962 //
1963 Status = EFI_DEVICE_ERROR;
1964 goto Error3;
1965 }
1966 AhciRegisters->AhciCmdListPciAddr = (EFI_AHCI_COMMAND_LIST *)(UINTN)AhciCmdListPciAddr;
1967
1968 //
1969 // Allocate memory for command table
1970 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
1971 //
1972 Buffer = NULL;
1973 MaxCommandTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
1974
1975 Status = PciIo->AllocateBuffer (
1976 PciIo,
1977 AllocateAnyPages,
1978 EfiBootServicesData,
1979 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize),
1980 &Buffer,
1981 0
1982 );
1983
1984 if (EFI_ERROR (Status)) {
1985 //
1986 // Free mapped resource.
1987 //
1988 Status = EFI_OUT_OF_RESOURCES;
1989 goto Error3;
1990 }
1991
1992 ZeroMem (Buffer, (UINTN)MaxCommandTableSize);
1993
1994 AhciRegisters->AhciCommandTable = Buffer;
1995 AhciRegisters->MaxCommandTableSize = MaxCommandTableSize;
1996 Bytes = (UINTN)MaxCommandTableSize;
1997
1998 Status = PciIo->Map (
1999 PciIo,
2000 EfiPciIoOperationBusMasterCommonBuffer,
2001 Buffer,
2002 &Bytes,
2003 &AhciCommandTablePciAddr,
2004 &AhciRegisters->MapCommandTable
2005 );
2006
2007 if (EFI_ERROR (Status) || (Bytes != MaxCommandTableSize)) {
2008 //
2009 // Map error or unable to map the whole cmd list buffer into a contiguous region.
2010 //
2011 Status = EFI_OUT_OF_RESOURCES;
2012 goto Error2;
2013 }
2014
2015 if ((!Support64Bit) && (AhciCommandTablePciAddr > 0x100000000ULL)) {
2016 //
2017 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
2018 //
2019 Status = EFI_DEVICE_ERROR;
2020 goto Error1;
2021 }
2022 AhciRegisters->AhciCommandTablePciAddr = (EFI_AHCI_COMMAND_TABLE *)(UINTN)AhciCommandTablePciAddr;
2023
2024 return EFI_SUCCESS;
2025 //
2026 // Map error or unable to map the whole CmdList buffer into a contiguous region.
2027 //
2028 Error1:
2029 PciIo->Unmap (
2030 PciIo,
2031 AhciRegisters->MapCommandTable
2032 );
2033 Error2:
2034 PciIo->FreeBuffer (
2035 PciIo,
2036 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandTableSize),
2037 AhciRegisters->AhciCommandTable
2038 );
2039 Error3:
2040 PciIo->Unmap (
2041 PciIo,
2042 AhciRegisters->MapCmdList
2043 );
2044 Error4:
2045 PciIo->FreeBuffer (
2046 PciIo,
2047 EFI_SIZE_TO_PAGES ((UINTN) MaxCommandListSize),
2048 AhciRegisters->AhciCmdList
2049 );
2050 Error5:
2051 PciIo->Unmap (
2052 PciIo,
2053 AhciRegisters->MapRFis
2054 );
2055 Error6:
2056 PciIo->FreeBuffer (
2057 PciIo,
2058 EFI_SIZE_TO_PAGES ((UINTN) MaxReceiveFisSize),
2059 AhciRegisters->AhciRFis
2060 );
2061
2062 return Status;
2063 }
2064
2065 /**
2066 Read logs from SATA device.
2067
2068 @param PciIo The PCI IO protocol instance.
2069 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2070 @param Port The number of port.
2071 @param PortMultiplier The multiplier of port.
2072 @param Buffer The data buffer to store SATA logs.
2073 @param LogNumber The address of the log.
2074 @param PageNumber The page number of the log.
2075
2076 @retval EFI_INVALID_PARAMETER PciIo, AhciRegisters or Buffer is NULL.
2077 @retval others Return status of AhciPioTransfer().
2078 **/
2079 EFI_STATUS
2080 AhciReadLogExt (
2081 IN EFI_PCI_IO_PROTOCOL *PciIo,
2082 IN EFI_AHCI_REGISTERS *AhciRegisters,
2083 IN UINT8 Port,
2084 IN UINT8 PortMultiplier,
2085 IN OUT UINT8 *Buffer,
2086 IN UINT8 LogNumber,
2087 IN UINT8 PageNumber
2088 )
2089 {
2090 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2091 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2092
2093 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) {
2094 return EFI_INVALID_PARAMETER;
2095 }
2096
2097 ///
2098 /// Read log from device
2099 ///
2100 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2101 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2102 ZeroMem (Buffer, 512);
2103
2104 AtaCommandBlock.AtaCommand = ATA_CMD_READ_LOG_EXT;
2105 AtaCommandBlock.AtaSectorCount = 1;
2106 AtaCommandBlock.AtaSectorNumber = LogNumber;
2107 AtaCommandBlock.AtaCylinderLow = PageNumber;
2108
2109 return AhciPioTransfer (
2110 PciIo,
2111 AhciRegisters,
2112 Port,
2113 PortMultiplier,
2114 NULL,
2115 0,
2116 TRUE,
2117 &AtaCommandBlock,
2118 &AtaStatusBlock,
2119 Buffer,
2120 512,
2121 ATA_ATAPI_TIMEOUT,
2122 NULL
2123 );
2124 }
2125
2126 /**
2127 Enable DEVSLP of the disk if supported.
2128
2129 @param PciIo The PCI IO protocol instance.
2130 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2131 @param Port The number of port.
2132 @param PortMultiplier The multiplier of port.
2133 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2134
2135 @retval EFI_SUCCESS The DEVSLP is enabled per policy successfully.
2136 @retval EFI_UNSUPPORTED The DEVSLP isn't supported by the controller/device and policy requires to enable it.
2137 **/
2138 EFI_STATUS
2139 AhciEnableDevSlp (
2140 IN EFI_PCI_IO_PROTOCOL *PciIo,
2141 IN EFI_AHCI_REGISTERS *AhciRegisters,
2142 IN UINT8 Port,
2143 IN UINT8 PortMultiplier,
2144 IN EFI_IDENTIFY_DATA *IdentifyData
2145 )
2146 {
2147 EFI_STATUS Status;
2148 UINT32 Offset;
2149 UINT32 Capability2;
2150 UINT8 LogData[512];
2151 DEVSLP_TIMING_VARIABLES DevSlpTiming;
2152 UINT32 PortCmd;
2153 UINT32 PortDevSlp;
2154
2155 if (mAtaAtapiPolicy->DeviceSleepEnable != 1) {
2156 return EFI_SUCCESS;
2157 }
2158
2159 //
2160 // Do not enable DevSlp if DevSlp is not supported.
2161 //
2162 Capability2 = AhciReadReg (PciIo, AHCI_CAPABILITY2_OFFSET);
2163 DEBUG ((DEBUG_INFO, "AHCI CAPABILITY2 = %08x\n", Capability2));
2164 if ((Capability2 & AHCI_CAP2_SDS) == 0) {
2165 return EFI_UNSUPPORTED;
2166 }
2167
2168 //
2169 // Do not enable DevSlp if DevSlp is not present
2170 // Do not enable DevSlp if Hot Plug or Mechanical Presence Switch is supported
2171 //
2172 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH;
2173 PortCmd = AhciReadReg (PciIo, Offset + EFI_AHCI_PORT_CMD);
2174 PortDevSlp = AhciReadReg (PciIo, Offset + AHCI_PORT_DEVSLP);
2175 DEBUG ((DEBUG_INFO, "Port CMD/DEVSLP = %08x / %08x\n", PortCmd, PortDevSlp));
2176 if (((PortDevSlp & AHCI_PORT_DEVSLP_DSP) == 0) ||
2177 ((PortCmd & (EFI_AHCI_PORT_CMD_HPCP | EFI_AHCI_PORT_CMD_MPSP)) != 0)
2178 ) {
2179 return EFI_UNSUPPORTED;
2180 }
2181
2182 //
2183 // Do not enable DevSlp if the device doesn't support DevSlp
2184 //
2185 DEBUG ((DEBUG_INFO, "IDENTIFY DEVICE: [77] = %04x, [78] = %04x, [79] = %04x\n",
2186 IdentifyData->AtaData.reserved_77,
2187 IdentifyData->AtaData.serial_ata_features_supported, IdentifyData->AtaData.serial_ata_features_enabled));
2188 if ((IdentifyData->AtaData.serial_ata_features_supported & BIT8) == 0) {
2189 DEBUG ((DEBUG_INFO, "DevSlp feature is not supported for device at port [%d] PortMultiplier [%d]!\n",
2190 Port, PortMultiplier));
2191 return EFI_UNSUPPORTED;
2192 }
2193
2194 //
2195 // Enable DevSlp when it is not enabled.
2196 //
2197 if ((IdentifyData->AtaData.serial_ata_features_enabled & BIT8) != 0) {
2198 Status = AhciDeviceSetFeature (
2199 PciIo, AhciRegisters, Port, 0, ATA_SUB_CMD_ENABLE_SATA_FEATURE, 0x09, ATA_ATAPI_TIMEOUT
2200 );
2201 DEBUG ((DEBUG_INFO, "DevSlp set feature for device at port [%d] PortMultiplier [%d] - %r\n",
2202 Port, PortMultiplier, Status));
2203 if (EFI_ERROR (Status)) {
2204 return Status;
2205 }
2206 }
2207
2208 Status = AhciReadLogExt(PciIo, AhciRegisters, Port, PortMultiplier, LogData, 0x30, 0x08);
2209
2210 //
2211 // Clear PxCMD.ST and PxDEVSLP.ADSE before updating PxDEVSLP.DITO and PxDEVSLP.MDAT.
2212 //
2213 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd & ~EFI_AHCI_PORT_CMD_ST);
2214 PortDevSlp &= ~AHCI_PORT_DEVSLP_ADSE;
2215 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2216
2217 //
2218 // Set PxDEVSLP.DETO and PxDEVSLP.MDAT to 0.
2219 //
2220 PortDevSlp &= ~AHCI_PORT_DEVSLP_DETO_MASK;
2221 PortDevSlp &= ~AHCI_PORT_DEVSLP_MDAT_MASK;
2222 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2223 DEBUG ((DEBUG_INFO, "Read Log Ext at port [%d] PortMultiplier [%d] - %r\n", Port, PortMultiplier, Status));
2224 if (EFI_ERROR (Status)) {
2225 //
2226 // Assume DEVSLP TIMING VARIABLES is not supported if the Identify Device Data log (30h, 8) fails
2227 //
2228 ZeroMem (&DevSlpTiming, sizeof (DevSlpTiming));
2229 } else {
2230 CopyMem (&DevSlpTiming, &LogData[48], sizeof (DevSlpTiming));
2231 DEBUG ((DEBUG_INFO, "DevSlpTiming: Supported(%d), Deto(%d), Madt(%d)\n",
2232 DevSlpTiming.Supported, DevSlpTiming.Deto, DevSlpTiming.Madt));
2233 }
2234
2235 //
2236 // Use 20ms as default DETO when DEVSLP TIMING VARIABLES is not supported or the DETO is 0.
2237 //
2238 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Deto == 0)) {
2239 DevSlpTiming.Deto = 20;
2240 }
2241
2242 //
2243 // Use 10ms as default MADT when DEVSLP TIMING VARIABLES is not supported or the MADT is 0.
2244 //
2245 if ((DevSlpTiming.Supported == 0) || (DevSlpTiming.Madt == 0)) {
2246 DevSlpTiming.Madt = 10;
2247 }
2248
2249 PortDevSlp |= DevSlpTiming.Deto << 2;
2250 PortDevSlp |= DevSlpTiming.Madt << 10;
2251 AhciOrReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2252
2253 if (mAtaAtapiPolicy->AggressiveDeviceSleepEnable == 1) {
2254 if ((Capability2 & AHCI_CAP2_SADM) != 0) {
2255 PortDevSlp &= ~AHCI_PORT_DEVSLP_DITO_MASK;
2256 PortDevSlp |= (625 << 15);
2257 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2258
2259 PortDevSlp |= AHCI_PORT_DEVSLP_ADSE;
2260 AhciWriteReg (PciIo, Offset + AHCI_PORT_DEVSLP, PortDevSlp);
2261 }
2262 }
2263
2264
2265 AhciWriteReg (PciIo, Offset + EFI_AHCI_PORT_CMD, PortCmd);
2266
2267 DEBUG ((DEBUG_INFO, "Enabled DevSlp feature at port [%d] PortMultiplier [%d], Port CMD/DEVSLP = %08x / %08x\n",
2268 Port, PortMultiplier, PortCmd, PortDevSlp));
2269
2270 return EFI_SUCCESS;
2271 }
2272
2273 /**
2274 Spin-up disk if IDD was incomplete or PUIS feature is enabled
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 IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
2281
2282 **/
2283 EFI_STATUS
2284 AhciSpinUpDisk (
2285 IN EFI_PCI_IO_PROTOCOL *PciIo,
2286 IN EFI_AHCI_REGISTERS *AhciRegisters,
2287 IN UINT8 Port,
2288 IN UINT8 PortMultiplier,
2289 IN OUT EFI_IDENTIFY_DATA *IdentifyData
2290 )
2291 {
2292 EFI_STATUS Status;
2293 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
2294 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
2295 UINT8 Buffer[512];
2296
2297 if (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_REQUIRED_IDD_INCOMPLETE) {
2298 //
2299 // Use SET_FEATURE subcommand to spin up the device.
2300 //
2301 Status = AhciDeviceSetFeature (
2302 PciIo, AhciRegisters, Port, PortMultiplier,
2303 ATA_SUB_CMD_PUIS_SET_DEVICE_SPINUP, 0x00, ATA_SPINUP_TIMEOUT
2304 );
2305 DEBUG ((DEBUG_INFO, "CMD_PUIS_SET_DEVICE_SPINUP for device at port [%d] PortMultiplier [%d] - %r!\n",
2306 Port, PortMultiplier, Status));
2307 if (EFI_ERROR (Status)) {
2308 return Status;
2309 }
2310 } else {
2311 ASSERT (IdentifyData->AtaData.specific_config == ATA_SPINUP_CFG_NOT_REQUIRED_IDD_INCOMPLETE);
2312
2313 //
2314 // Use READ_SECTORS to spin up the device if SpinUp SET FEATURE subcommand is not supported
2315 //
2316 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
2317 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
2318 //
2319 // Perform READ SECTORS PIO Data-In command to Read LBA 0
2320 //
2321 AtaCommandBlock.AtaCommand = ATA_CMD_READ_SECTORS;
2322 AtaCommandBlock.AtaSectorCount = 0x1;
2323
2324 Status = AhciPioTransfer (
2325 PciIo,
2326 AhciRegisters,
2327 Port,
2328 PortMultiplier,
2329 NULL,
2330 0,
2331 TRUE,
2332 &AtaCommandBlock,
2333 &AtaStatusBlock,
2334 &Buffer,
2335 sizeof (Buffer),
2336 ATA_SPINUP_TIMEOUT,
2337 NULL
2338 );
2339 DEBUG ((DEBUG_INFO, "Read LBA 0 for device at port [%d] PortMultiplier [%d] - %r!\n",
2340 Port, PortMultiplier, Status));
2341 if (EFI_ERROR (Status)) {
2342 return Status;
2343 }
2344 }
2345
2346 //
2347 // Read the complete IDENTIFY DEVICE data.
2348 //
2349 ZeroMem (IdentifyData, sizeof (*IdentifyData));
2350 Status = AhciIdentify (PciIo, AhciRegisters, Port, PortMultiplier, IdentifyData);
2351 if (EFI_ERROR (Status)) {
2352 DEBUG ((DEBUG_ERROR, "Read IDD failed for device at port [%d] PortMultiplier [%d] - %r!\n",
2353 Port, PortMultiplier, Status));
2354 return Status;
2355 }
2356
2357 DEBUG ((DEBUG_INFO, "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
2358 IdentifyData->AtaData.config, IdentifyData->AtaData.specific_config,
2359 IdentifyData->AtaData.command_set_supported_83, IdentifyData->AtaData.command_set_feature_enb_86));
2360 //
2361 // Check if IDD is incomplete
2362 //
2363 if ((IdentifyData->AtaData.config & BIT2) != 0) {
2364 return EFI_DEVICE_ERROR;
2365 }
2366
2367 return EFI_SUCCESS;
2368 }
2369
2370 /**
2371 Enable/disable/skip PUIS of the disk according to policy.
2372
2373 @param PciIo The PCI IO protocol instance.
2374 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
2375 @param Port The number of port.
2376 @param PortMultiplier The multiplier of port.
2377
2378 **/
2379 EFI_STATUS
2380 AhciPuisEnable (
2381 IN EFI_PCI_IO_PROTOCOL *PciIo,
2382 IN EFI_AHCI_REGISTERS *AhciRegisters,
2383 IN UINT8 Port,
2384 IN UINT8 PortMultiplier
2385 )
2386 {
2387 EFI_STATUS Status;
2388
2389 Status = EFI_SUCCESS;
2390 if (mAtaAtapiPolicy->PuisEnable == 0) {
2391 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_DISABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2392 } else if (mAtaAtapiPolicy->PuisEnable == 1) {
2393 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, PortMultiplier, ATA_SUB_CMD_ENABLE_PUIS, 0x00, ATA_ATAPI_TIMEOUT);
2394 }
2395 DEBUG ((DEBUG_INFO, "%a PUIS feature at port [%d] PortMultiplier [%d] - %r!\n",
2396 (mAtaAtapiPolicy->PuisEnable == 0) ? "Disable" : (
2397 (mAtaAtapiPolicy->PuisEnable == 1) ? "Enable" : "Skip"
2398 ), Port, PortMultiplier, Status));
2399 return Status;
2400 }
2401
2402 /**
2403 Initialize ATA host controller at AHCI mode.
2404
2405 The function is designed to initialize ATA host controller.
2406
2407 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
2408
2409 **/
2410 EFI_STATUS
2411 EFIAPI
2412 AhciModeInitialization (
2413 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
2414 )
2415 {
2416 EFI_STATUS Status;
2417 EFI_PCI_IO_PROTOCOL *PciIo;
2418 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
2419 UINT32 Capability;
2420 UINT8 MaxPortNumber;
2421 UINT32 PortImplementBitMap;
2422
2423 EFI_AHCI_REGISTERS *AhciRegisters;
2424
2425 UINT8 Port;
2426 DATA_64 Data64;
2427 UINT32 Offset;
2428 UINT32 Data;
2429 EFI_IDENTIFY_DATA Buffer;
2430 EFI_ATA_DEVICE_TYPE DeviceType;
2431 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
2432 EFI_ATA_TRANSFER_MODE TransferMode;
2433 UINT32 PhyDetectDelay;
2434 UINT32 Value;
2435
2436 if (Instance == NULL) {
2437 return EFI_INVALID_PARAMETER;
2438 }
2439
2440 PciIo = Instance->PciIo;
2441 IdeInit = Instance->IdeControllerInit;
2442
2443 Status = AhciReset (PciIo, EFI_AHCI_BUS_RESET_TIMEOUT);
2444
2445 if (EFI_ERROR (Status)) {
2446 return EFI_DEVICE_ERROR;
2447 }
2448
2449 //
2450 // Collect AHCI controller information
2451 //
2452 Capability = AhciReadReg (PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2453
2454 //
2455 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
2456 //
2457 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
2458
2459 if ((Value & EFI_AHCI_GHC_ENABLE) == 0) {
2460 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
2461 }
2462
2463 //
2464 // Enable 64-bit DMA support in the PCI layer if this controller
2465 // supports it.
2466 //
2467 if ((Capability & EFI_AHCI_CAP_S64A) != 0) {
2468 Status = PciIo->Attributes (
2469 PciIo,
2470 EfiPciIoAttributeOperationEnable,
2471 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
2472 NULL
2473 );
2474 if (EFI_ERROR (Status)) {
2475 DEBUG ((EFI_D_WARN,
2476 "AhciModeInitialization: failed to enable 64-bit DMA on 64-bit capable controller (%r)\n",
2477 Status));
2478 }
2479 }
2480
2481 //
2482 // Get the number of command slots per port supported by this HBA.
2483 //
2484 MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1);
2485
2486 //
2487 // Get the bit map of those ports exposed by this HBA.
2488 // It indicates which ports that the HBA supports are available for software to use.
2489 //
2490 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
2491
2492 AhciRegisters = &Instance->AhciRegisters;
2493 Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters);
2494
2495 if (EFI_ERROR (Status)) {
2496 return EFI_OUT_OF_RESOURCES;
2497 }
2498
2499 for (Port = 0; Port < EFI_AHCI_MAX_PORTS; Port ++) {
2500 if ((PortImplementBitMap & (((UINT32)BIT0) << Port)) != 0) {
2501 //
2502 // According to AHCI spec, MaxPortNumber should be equal or greater than the number of implemented ports.
2503 //
2504 if ((MaxPortNumber--) == 0) {
2505 //
2506 // Should never be here.
2507 //
2508 ASSERT (FALSE);
2509 return EFI_SUCCESS;
2510 }
2511
2512 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port);
2513
2514 //
2515 // Initialize FIS Base Address Register and Command List Base Address Register for use.
2516 //
2517 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFisPciAddr) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
2518 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;
2519 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2520 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;
2521 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2522
2523 Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdListPciAddr);
2524 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;
2525 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2526 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;
2527 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2528
2529 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2530 Data = AhciReadReg (PciIo, Offset);
2531 if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {
2532 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_POD);
2533 }
2534
2535 if ((Capability & EFI_AHCI_CAP_SSS) != 0) {
2536 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_SUD);
2537 }
2538
2539 //
2540 // Disable aggressive power management.
2541 //
2542 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
2543 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_INIT);
2544 //
2545 // Disable the reporting of the corresponding interrupt to system software.
2546 //
2547 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE;
2548 AhciAndReg (PciIo, Offset, 0);
2549
2550 //
2551 // Now inform the IDE Controller Init Module.
2552 //
2553 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, Port);
2554
2555 //
2556 // Enable FIS Receive DMA engine for the first D2H FIS.
2557 //
2558 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2559 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
2560
2561 //
2562 // Wait for the Phy to detect the presence of a device.
2563 //
2564 PhyDetectDelay = EFI_AHCI_BUS_PHY_DETECT_TIMEOUT;
2565 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
2566 do {
2567 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
2568 if ((Data == EFI_AHCI_PORT_SSTS_DET_PCE) || (Data == EFI_AHCI_PORT_SSTS_DET)) {
2569 break;
2570 }
2571
2572 MicroSecondDelay (1000);
2573 PhyDetectDelay--;
2574 } while (PhyDetectDelay > 0);
2575
2576 if (PhyDetectDelay == 0) {
2577 //
2578 // No device detected at this port.
2579 // Clear PxCMD.SUD for those ports at which there are no device present.
2580 //
2581 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2582 AhciAndReg (PciIo, Offset, (UINT32) ~(EFI_AHCI_PORT_CMD_SUD));
2583 continue;
2584 }
2585
2586 //
2587 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
2588 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
2589 //
2590 PhyDetectDelay = 16 * 1000;
2591 do {
2592 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
2593 if (AhciReadReg(PciIo, Offset) != 0) {
2594 AhciWriteReg (PciIo, Offset, AhciReadReg(PciIo, Offset));
2595 }
2596 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
2597
2598 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_TFD_MASK;
2599 if (Data == 0) {
2600 break;
2601 }
2602
2603 MicroSecondDelay (1000);
2604 PhyDetectDelay--;
2605 } while (PhyDetectDelay > 0);
2606
2607 if (PhyDetectDelay == 0) {
2608 DEBUG ((EFI_D_ERROR, "Port %d Device presence detected but phy not ready (TFD=0x%X)\n", Port, Data));
2609 continue;
2610 }
2611
2612 //
2613 // When the first D2H register FIS is received, the content of PxSIG register is updated.
2614 //
2615 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;
2616 Status = AhciWaitMmioSet (
2617 PciIo,
2618 Offset,
2619 0x0000FFFF,
2620 0x00000101,
2621 EFI_TIMER_PERIOD_SECONDS(16)
2622 );
2623 if (EFI_ERROR (Status)) {
2624 continue;
2625 }
2626
2627 Data = AhciReadReg (PciIo, Offset);
2628 if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATAPI_DEVICE_SIG) {
2629 Status = AhciIdentifyPacket (PciIo, AhciRegisters, Port, 0, &Buffer);
2630
2631 if (EFI_ERROR (Status)) {
2632 continue;
2633 }
2634
2635 DeviceType = EfiIdeCdrom;
2636 } else if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATA_DEVICE_SIG) {
2637 Status = AhciIdentify (PciIo, AhciRegisters, Port, 0, &Buffer);
2638
2639 if (EFI_ERROR (Status)) {
2640 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));
2641 continue;
2642 }
2643
2644 DEBUG ((
2645 DEBUG_INFO, "IDENTIFY DEVICE: [0] = %016x, [2] = %016x, [83] = %016x, [86] = %016x\n",
2646 Buffer.AtaData.config, Buffer.AtaData.specific_config,
2647 Buffer.AtaData.command_set_supported_83, Buffer.AtaData.command_set_feature_enb_86
2648 ));
2649 if ((Buffer.AtaData.config & BIT2) != 0) {
2650 //
2651 // SpinUp disk if device reported incomplete IDENTIFY DEVICE.
2652 //
2653 Status = AhciSpinUpDisk (
2654 PciIo,
2655 AhciRegisters,
2656 Port,
2657 0,
2658 &Buffer
2659 );
2660 if (EFI_ERROR (Status)) {
2661 DEBUG ((DEBUG_ERROR, "Spin up standby device failed - %r\n", Status));
2662 continue;
2663 }
2664 }
2665
2666 DeviceType = EfiIdeHarddisk;
2667 } else {
2668 continue;
2669 }
2670 DEBUG ((DEBUG_INFO, "port [%d] port multitplier [%d] has a [%a]\n",
2671 Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk"));
2672
2673 //
2674 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2675 //
2676 if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {
2677 AhciAtaSmartSupport (
2678 PciIo,
2679 AhciRegisters,
2680 Port,
2681 0,
2682 &Buffer,
2683 NULL
2684 );
2685 }
2686
2687 //
2688 // Submit identify data to IDE controller init driver
2689 //
2690 IdeInit->SubmitData (IdeInit, Port, 0, &Buffer);
2691
2692 //
2693 // Now start to config ide device parameter and transfer mode.
2694 //
2695 Status = IdeInit->CalculateMode (
2696 IdeInit,
2697 Port,
2698 0,
2699 &SupportedModes
2700 );
2701 if (EFI_ERROR (Status)) {
2702 DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2703 continue;
2704 }
2705
2706 //
2707 // Set best supported PIO mode on this IDE device
2708 //
2709 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2710 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2711 } else {
2712 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2713 }
2714
2715 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
2716
2717 //
2718 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't
2719 // be set together. Only one DMA mode can be set to a device. If setting
2720 // DMA mode operation fails, we can continue moving on because we only use
2721 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2722 //
2723 if (SupportedModes->UdmaMode.Valid) {
2724 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2725 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
2726 } else if (SupportedModes->MultiWordDmaMode.Valid) {
2727 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2728 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
2729 }
2730
2731 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode), ATA_ATAPI_TIMEOUT);
2732 if (EFI_ERROR (Status)) {
2733 DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2734 continue;
2735 }
2736
2737 //
2738 // Found a ATA or ATAPI device, add it into the device list.
2739 //
2740 CreateNewDeviceInfo (Instance, Port, 0xFFFF, DeviceType, &Buffer);
2741 if (DeviceType == EfiIdeHarddisk) {
2742 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));
2743 AhciEnableDevSlp (
2744 PciIo,
2745 AhciRegisters,
2746 Port,
2747 0,
2748 &Buffer
2749 );
2750 }
2751
2752 //
2753 // Enable/disable PUIS according to policy setting if PUIS is capable (Word[83].BIT5 is set).
2754 //
2755 if ((Buffer.AtaData.command_set_supported_83 & BIT5) != 0) {
2756 Status = AhciPuisEnable (
2757 PciIo,
2758 AhciRegisters,
2759 Port,
2760 0
2761 );
2762 if (EFI_ERROR (Status)) {
2763 DEBUG ((DEBUG_ERROR, "PUIS enable/disable failed, Status = %r\n", Status));
2764 continue;
2765 }
2766 }
2767 }
2768 }
2769
2770 return EFI_SUCCESS;
2771 }
2772