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