]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
S.M.A.R.T feature enable
[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, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "AtaAtapiPassThru.h"
16
17 /**
18 Read AHCI Operation register.
19
20 @param PciIo The PCI IO protocol instance.
21 @param Offset The operation register offset.
22
23 @return The register content read.
24
25 **/
26 UINT32
27 EFIAPI
28 AhciReadReg (
29 IN EFI_PCI_IO_PROTOCOL *PciIo,
30 IN UINT32 Offset
31 )
32 {
33 UINT32 Data;
34
35 ASSERT (PciIo != NULL);
36
37 Data = 0;
38
39 PciIo->Mem.Read (
40 PciIo,
41 EfiPciIoWidthUint32,
42 EFI_AHCI_BAR_INDEX,
43 (UINT64) Offset,
44 1,
45 &Data
46 );
47
48 return Data;
49 }
50
51 /**
52 Write AHCI Operation register.
53
54 @param PciIo The PCI IO protocol instance.
55 @param Offset The operation register offset.
56 @param Data The data used to write down.
57
58 **/
59 VOID
60 EFIAPI
61 AhciWriteReg (
62 IN EFI_PCI_IO_PROTOCOL *PciIo,
63 IN UINT32 Offset,
64 IN UINT32 Data
65 )
66 {
67 ASSERT (PciIo != NULL);
68
69 PciIo->Mem.Write (
70 PciIo,
71 EfiPciIoWidthUint32,
72 EFI_AHCI_BAR_INDEX,
73 (UINT64) Offset,
74 1,
75 &Data
76 );
77
78 return ;
79 }
80
81 /**
82 Do AND operation with the value of AHCI Operation register.
83
84 @param PciIo The PCI IO protocol instance.
85 @param Offset The operation register offset.
86 @param AndData The data used to do AND operation.
87
88 **/
89 VOID
90 EFIAPI
91 AhciAndReg (
92 IN EFI_PCI_IO_PROTOCOL *PciIo,
93 IN UINT32 Offset,
94 IN UINT32 AndData
95 )
96 {
97 UINT32 Data;
98
99 ASSERT (PciIo != NULL);
100
101 Data = AhciReadReg (PciIo, Offset);
102
103 Data &= AndData;
104
105 AhciWriteReg (PciIo, Offset, Data);
106 }
107
108 /**
109 Do OR operation with the value of AHCI Operation register.
110
111 @param PciIo The PCI IO protocol instance.
112 @param Offset The operation register offset.
113 @param OrData The data used to do OR operation.
114
115 **/
116 VOID
117 EFIAPI
118 AhciOrReg (
119 IN EFI_PCI_IO_PROTOCOL *PciIo,
120 IN UINT32 Offset,
121 IN UINT32 OrData
122 )
123 {
124 UINT32 Data;
125
126 ASSERT (PciIo != NULL);
127
128 Data = AhciReadReg (PciIo, Offset);
129
130 Data |= OrData;
131
132 AhciWriteReg (PciIo, Offset, Data);
133 }
134
135 /**
136 Wait for memory set to the test value.
137
138 @param PciIo The PCI IO protocol instance.
139 @param Offset The memory address to test.
140 @param MaskValue The mask value of memory.
141 @param TestValue The test value of memory.
142 @param Timeout The time out value for wait memory set.
143
144 @retval EFI_DEVICE_ERROR The memory is not set.
145 @retval EFI_TIMEOUT The memory setting is time out.
146 @retval EFI_SUCCESS The memory is correct set.
147
148 **/
149 EFI_STATUS
150 EFIAPI
151 AhciWaitMemSet (
152 IN EFI_PCI_IO_PROTOCOL *PciIo,
153 IN UINT32 Offset,
154 IN UINT32 MaskValue,
155 IN UINT32 TestValue,
156 IN UINT64 Timeout
157 )
158 {
159 UINT32 Value;
160 UINT32 Delay;
161
162 Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
163
164 do {
165 Value = AhciReadReg (PciIo, Offset) & MaskValue;
166
167 if (Value == TestValue) {
168 return EFI_SUCCESS;
169 }
170
171 //
172 // Stall for 100 microseconds.
173 //
174 MicroSecondDelay (100);
175
176 Delay--;
177
178 } while (Delay > 0);
179
180 if (Delay == 0) {
181 return EFI_TIMEOUT;
182 }
183
184 return EFI_DEVICE_ERROR;
185 }
186
187 /**
188 Check if the device is still on port. It also checks if the AHCI controller
189 supports the address and data count will be transfered.
190
191 @param PciIo The PCI IO protocol instance.
192 @param Port The number of port.
193
194 @retval EFI_SUCCESS The device is attached to port and the transfer data is
195 supported by AHCI controller.
196 @retval EFI_UNSUPPORTED The transfer address and count is not supported by AHCI
197 controller.
198 @retval EFI_NOT_READY The physical communication between AHCI controller and device
199 is not ready.
200
201 **/
202 EFI_STATUS
203 EFIAPI
204 AhciCheckDeviceStatus (
205 IN EFI_PCI_IO_PROTOCOL *PciIo,
206 IN UINT8 Port
207 )
208 {
209 UINT32 Data;
210 UINT32 Offset;
211
212 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
213
214 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
215
216 if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) {
217 return EFI_SUCCESS;
218 }
219
220 return EFI_NOT_READY;
221 }
222
223 /**
224
225 Clear the port interrupt and error status. It will also clear
226 HBA interrupt status.
227
228 @param PciIo The PCI IO protocol instance.
229 @param Port The number of port.
230
231 **/
232 VOID
233 EFIAPI
234 AhciClearPortStatus (
235 IN EFI_PCI_IO_PROTOCOL *PciIo,
236 IN UINT8 Port
237 )
238 {
239 UINT32 Offset;
240
241 //
242 // Clear any error status
243 //
244 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
245 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
246
247 //
248 // Clear any port interrupt status
249 //
250 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
251 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
252
253 //
254 // Clear any HBA interrupt status
255 //
256 AhciWriteReg (PciIo, EFI_AHCI_IS_OFFSET, AhciReadReg (PciIo, EFI_AHCI_IS_OFFSET));
257 }
258
259 /**
260 Enable the FIS running for giving port.
261
262 @param PciIo The PCI IO protocol instance.
263 @param Port The number of port.
264 @param Timeout The timeout value of enabling FIS.
265
266 @retval EFI_DEVICE_ERROR The FIS enable setting fails.
267 @retval EFI_TIMEOUT The FIS enable setting is time out.
268 @retval EFI_SUCCESS The FIS enable successfully.
269
270 **/
271 EFI_STATUS
272 EFIAPI
273 AhciEnableFisReceive (
274 IN EFI_PCI_IO_PROTOCOL *PciIo,
275 IN UINT8 Port,
276 IN UINT64 Timeout
277 )
278 {
279 UINT32 Offset;
280
281 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
282 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);
283
284 return AhciWaitMemSet (
285 PciIo,
286 Offset,
287 EFI_AHCI_PORT_CMD_FR,
288 EFI_AHCI_PORT_CMD_FR,
289 Timeout
290 );
291 }
292
293 /**
294 Disable the FIS running for giving port.
295
296 @param PciIo The PCI IO protocol instance.
297 @param Port The number of port.
298 @param Timeout The timeout value of disabling FIS.
299
300 @retval EFI_DEVICE_ERROR The FIS disable setting fails.
301 @retval EFI_TIMEOUT The FIS disable setting is time out.
302 @retval EFI_UNSUPPORTED The port is in running state.
303 @retval EFI_SUCCESS The FIS disable successfully.
304
305 **/
306 EFI_STATUS
307 EFIAPI
308 AhciDisableFisReceive (
309 IN EFI_PCI_IO_PROTOCOL *PciIo,
310 IN UINT8 Port,
311 IN UINT64 Timeout
312 )
313 {
314 UINT32 Offset;
315 UINT32 Data;
316
317 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
318 Data = AhciReadReg (PciIo, Offset);
319
320 //
321 // Before disabling Fis receive, the DMA engine of the port should NOT be in running status.
322 //
323 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) != 0) {
324 return EFI_UNSUPPORTED;
325 }
326
327 //
328 // Check if the Fis receive DMA engine for the port is running.
329 //
330 if ((Data & EFI_AHCI_PORT_CMD_FR) != EFI_AHCI_PORT_CMD_FR) {
331 return EFI_SUCCESS;
332 }
333
334 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));
335
336 return AhciWaitMemSet (
337 PciIo,
338 Offset,
339 EFI_AHCI_PORT_CMD_FR,
340 0,
341 Timeout
342 );
343 }
344
345
346
347 /**
348 Build the command list, command table and prepare the fis receiver.
349
350 @param PciIo The PCI IO protocol instance.
351 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
352 @param Port The number of port.
353 @param PortMultiplier The timeout value of stop.
354 @param CommandFis The control fis will be used for the transfer.
355 @param CommandList The command list will be used for the transfer.
356 @param AtapiCommand The atapi command will be used for the transfer.
357 @param AtapiCommandLength The length of the atapi command.
358 @param CommandSlotNumber The command slot will be used for the transfer.
359 @param DataPhysicalAddr The pointer to the data buffer pci bus master address.
360 @param DataLength The data count to be transferred.
361
362 **/
363 VOID
364 EFIAPI
365 AhciBuildCommand (
366 IN EFI_PCI_IO_PROTOCOL *PciIo,
367 IN EFI_AHCI_REGISTERS *AhciRegisters,
368 IN UINT8 Port,
369 IN UINT8 PortMultiplier,
370 IN EFI_AHCI_COMMAND_FIS *CommandFis,
371 IN EFI_AHCI_COMMAND_LIST *CommandList,
372 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
373 IN UINT8 AtapiCommandLength,
374 IN UINT8 CommandSlotNumber,
375 IN OUT VOID *DataPhysicalAddr,
376 IN UINT64 DataLength
377 )
378 {
379 UINT64 BaseAddr;
380 UINT64 PrdtNumber;
381 UINT64 PrdtIndex;
382 UINTN RemainedData;
383 UINTN MemAddr;
384 DATA_64 Data64;
385 UINT32 Offset;
386
387 //
388 // Filling the PRDT
389 //
390 PrdtNumber = (DataLength + EFI_AHCI_MAX_DATA_PER_PRDT - 1) / EFI_AHCI_MAX_DATA_PER_PRDT;
391
392 //
393 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
394 // It also limits that the maximum amount of the PRDT entry in the command table
395 // is 65535.
396 //
397 ASSERT (PrdtNumber <= 65535);
398
399 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
400
401 BaseAddr = Data64.Uint64;
402
403 ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
404
405 ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
406
407 CommandFis->AhciCFisPmNum = PortMultiplier;
408
409 CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
410
411 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
412 if (AtapiCommand != NULL) {
413 CopyMem (
414 &AhciRegisters->AhciCommandTable->AtapiCmd,
415 AtapiCommand,
416 AtapiCommandLength
417 );
418
419 CommandList->AhciCmdA = 1;
420 CommandList->AhciCmdP = 1;
421 CommandList->AhciCmdC = (DataLength == 0) ? 1 : 0;
422
423 AhciOrReg (PciIo, Offset, (EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
424 } else {
425 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_DLAE | EFI_AHCI_PORT_CMD_ATAPI));
426 }
427
428 RemainedData = (UINTN) DataLength;
429 MemAddr = (UINTN) DataPhysicalAddr;
430 CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber;
431
432 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
433 if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {
434 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
435 } else {
436 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;
437 }
438
439 Data64.Uint64 = (UINT64)MemAddr;
440 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
441 AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
442 RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
443 MemAddr += EFI_AHCI_MAX_DATA_PER_PRDT;
444 }
445
446 //
447 // Set the last PRDT to Interrupt On Complete
448 //
449 if (PrdtNumber > 0) {
450 AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
451 }
452
453 CopyMem (
454 (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
455 CommandList,
456 sizeof (EFI_AHCI_COMMAND_LIST)
457 );
458
459 Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr;
460 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
461 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
462 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;
463
464 }
465
466 /**
467 Buid a command FIS.
468
469 @param CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data structure.
470 @param AtaCommandBlock A pointer to the AhciBuildCommandFis data structure.
471
472 **/
473 VOID
474 EFIAPI
475 AhciBuildCommandFis (
476 IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,
477 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
478 )
479 {
480 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
481
482 CmdFis->AhciCFisType = EFI_AHCI_FIS_REGISTER_H2D;
483 //
484 // Indicator it's a command
485 //
486 CmdFis->AhciCFisCmdInd = 0x1;
487 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
488
489 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
490 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
491
492 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
493 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
494
495 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
496 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
497
498 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
499 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
500
501 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
502 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
503
504 CmdFis->AhciCFisDevHead = (UINT8) (AtaCommandBlock->AtaDeviceHead | 0xE0);
505 }
506
507 /**
508 Start a PIO data transfer on specific port.
509
510 @param PciIo The PCI IO protocol instance.
511 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
512 @param Port The number of port.
513 @param PortMultiplier The timeout value of stop.
514 @param AtapiCommand The atapi command will be used for the transfer.
515 @param AtapiCommandLength The length of the atapi command.
516 @param Read The transfer direction.
517 @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
518 @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
519 @param MemoryAddr The pointer to the data buffer.
520 @param DataCount The data count to be transferred.
521 @param Timeout The timeout value of non data transfer.
522
523 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
524 @retval EFI_TIMEOUT The operation is time out.
525 @retval EFI_UNSUPPORTED The device is not ready for transfer.
526 @retval EFI_SUCCESS The PIO data transfer executes successfully.
527
528 **/
529 EFI_STATUS
530 EFIAPI
531 AhciPioTransfer (
532 IN EFI_PCI_IO_PROTOCOL *PciIo,
533 IN EFI_AHCI_REGISTERS *AhciRegisters,
534 IN UINT8 Port,
535 IN UINT8 PortMultiplier,
536 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
537 IN UINT8 AtapiCommandLength,
538 IN BOOLEAN Read,
539 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
540 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
541 IN OUT VOID *MemoryAddr,
542 IN UINT32 DataCount,
543 IN UINT64 Timeout
544 )
545 {
546 EFI_STATUS Status;
547 UINTN FisBaseAddr;
548 UINT32 Offset;
549 UINT32 Value;
550 EFI_PHYSICAL_ADDRESS PhyAddr;
551 VOID *Map;
552 UINTN MapLength;
553 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
554 UINT32 Delay;
555 EFI_AHCI_COMMAND_FIS CFis;
556 EFI_AHCI_COMMAND_LIST CmdList;
557
558 if (Read) {
559 Flag = EfiPciIoOperationBusMasterWrite;
560 } else {
561 Flag = EfiPciIoOperationBusMasterRead;
562 }
563
564 //
565 // construct command list and command table with pci bus address
566 //
567 MapLength = DataCount;
568 Status = PciIo->Map (
569 PciIo,
570 Flag,
571 MemoryAddr,
572 &MapLength,
573 &PhyAddr,
574 &Map
575 );
576
577 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
578 return EFI_OUT_OF_RESOURCES;
579 }
580
581 //
582 // Package read needed
583 //
584 AhciBuildCommandFis (&CFis, AtaCommandBlock);
585
586 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
587
588 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
589 CmdList.AhciCmdW = Read ? 0 : 1;
590
591 AhciBuildCommand (
592 PciIo,
593 AhciRegisters,
594 Port,
595 PortMultiplier,
596 &CFis,
597 &CmdList,
598 AtapiCommand,
599 AtapiCommandLength,
600 0,
601 (VOID *)(UINTN)PhyAddr,
602 DataCount
603 );
604
605 Status = AhciStartCommand (
606 PciIo,
607 Port,
608 0,
609 Timeout
610 );
611 if (EFI_ERROR (Status)) {
612 goto Exit;
613 }
614
615 //
616 // Checking the status and wait the driver sending data
617 //
618 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
619 //
620 // Wait device sends the PIO setup fis before data transfer
621 //
622 Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
623 do {
624 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);
625
626 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_PIO_SETUP) {
627 break;
628 }
629
630 //
631 // Stall for 100 microseconds.
632 //
633 MicroSecondDelay(100);
634
635 Delay--;
636 } while (Delay > 0);
637
638 if (Delay == 0) {
639 Status = EFI_TIMEOUT;
640 goto Exit;
641 }
642
643 //
644 // Wait for command compelte
645 //
646 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
647 Status = AhciWaitMemSet (
648 PciIo,
649 Offset,
650 0xFFFFFFFF,
651 0,
652 Timeout
653 );
654
655 if (EFI_ERROR (Status)) {
656 goto Exit;
657 }
658
659 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
660 Status = AhciWaitMemSet (
661 PciIo,
662 Offset,
663 EFI_AHCI_PORT_IS_PSS,
664 EFI_AHCI_PORT_IS_PSS,
665 Timeout
666 );
667 if (EFI_ERROR (Status)) {
668 goto Exit;
669 }
670
671 Exit:
672 AhciStopCommand (
673 PciIo,
674 Port,
675 Timeout
676 );
677
678 AhciDisableFisReceive (
679 PciIo,
680 Port,
681 Timeout
682 );
683
684 PciIo->Unmap (
685 PciIo,
686 Map
687 );
688
689 return Status;
690 }
691
692 /**
693 Start a DMA data transfer on specific port
694
695 @param PciIo The PCI IO protocol instance.
696 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
697 @param Port The number of port.
698 @param PortMultiplier The timeout value of stop.
699 @param AtapiCommand The atapi command will be used for the transfer.
700 @param AtapiCommandLength The length of the atapi command.
701 @param Read The transfer direction.
702 @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
703 @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
704 @param MemoryAddr The pointer to the data buffer.
705 @param DataCount The data count to be transferred.
706 @param Timeout The timeout value of non data transfer.
707
708 @retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
709 @retval EFI_TIMEOUT The operation is time out.
710 @retval EFI_UNSUPPORTED The device is not ready for transfer.
711 @retval EFI_SUCCESS The DMA data transfer executes successfully.
712
713 **/
714 EFI_STATUS
715 EFIAPI
716 AhciDmaTransfer (
717 IN EFI_PCI_IO_PROTOCOL *PciIo,
718 IN EFI_AHCI_REGISTERS *AhciRegisters,
719 IN UINT8 Port,
720 IN UINT8 PortMultiplier,
721 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
722 IN UINT8 AtapiCommandLength,
723 IN BOOLEAN Read,
724 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
725 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
726 IN OUT VOID *MemoryAddr,
727 IN UINTN DataCount,
728 IN UINT64 Timeout
729 )
730 {
731 EFI_STATUS Status;
732 UINT32 Offset;
733 EFI_PHYSICAL_ADDRESS PhyAddr;
734 VOID *Map;
735 UINTN MapLength;
736 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
737 EFI_AHCI_COMMAND_FIS CFis;
738 EFI_AHCI_COMMAND_LIST CmdList;
739
740 if (Read) {
741 Flag = EfiPciIoOperationBusMasterWrite;
742 } else {
743 Flag = EfiPciIoOperationBusMasterRead;
744 }
745
746 //
747 // construct command list and command table with pci bus address
748 //
749 MapLength = DataCount;
750 Status = PciIo->Map (
751 PciIo,
752 Flag,
753 MemoryAddr,
754 &MapLength,
755 &PhyAddr,
756 &Map
757 );
758
759 if (EFI_ERROR (Status) || (DataCount != MapLength)) {
760 return EFI_OUT_OF_RESOURCES;
761 }
762
763 //
764 // Package read needed
765 //
766 AhciBuildCommandFis (&CFis, AtaCommandBlock);
767
768 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
769
770 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
771 CmdList.AhciCmdW = Read ? 0 : 1;
772
773 AhciBuildCommand (
774 PciIo,
775 AhciRegisters,
776 Port,
777 PortMultiplier,
778 &CFis,
779 &CmdList,
780 AtapiCommand,
781 AtapiCommandLength,
782 0,
783 (VOID *)(UINTN)PhyAddr,
784 DataCount
785 );
786
787 Status = AhciStartCommand (
788 PciIo,
789 Port,
790 0,
791 Timeout
792 );
793 if (EFI_ERROR (Status)) {
794 goto Exit;
795 }
796
797 //
798 // Wait device PRD processed
799 //
800 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
801 Status = AhciWaitMemSet (
802 PciIo,
803 Offset,
804 EFI_AHCI_PORT_IS_DPS,
805 EFI_AHCI_PORT_IS_DPS,
806 Timeout
807 );
808
809 if (EFI_ERROR (Status)) {
810 goto Exit;
811 }
812
813 //
814 // Wait for command compelte
815 //
816 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
817 Status = AhciWaitMemSet (
818 PciIo,
819 Offset,
820 0xFFFFFFFF,
821 0,
822 Timeout
823 );
824 if (EFI_ERROR (Status)) {
825 goto Exit;
826 }
827
828 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;
829 Status = AhciWaitMemSet (
830 PciIo,
831 Offset,
832 EFI_AHCI_PORT_IS_DHRS,
833 EFI_AHCI_PORT_IS_DHRS,
834 Timeout
835 );
836 if (EFI_ERROR (Status)) {
837 goto Exit;
838 }
839
840 Exit:
841 AhciStopCommand (
842 PciIo,
843 Port,
844 Timeout
845 );
846
847 AhciDisableFisReceive (
848 PciIo,
849 Port,
850 Timeout
851 );
852
853 PciIo->Unmap (
854 PciIo,
855 Map
856 );
857
858 return Status;
859 }
860
861 /**
862 Start a non data transfer on specific port.
863
864 @param PciIo The PCI IO protocol instance.
865 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
866 @param Port The number of port.
867 @param PortMultiplier The timeout value of stop.
868 @param AtapiCommand The atapi command will be used for the transfer.
869 @param AtapiCommandLength The length of the atapi command.
870 @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
871 @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
872 @param Timeout The timeout value of non data transfer.
873
874 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
875 @retval EFI_TIMEOUT The operation is time out.
876 @retval EFI_UNSUPPORTED The device is not ready for transfer.
877 @retval EFI_SUCCESS The non data transfer executes successfully.
878
879 **/
880 EFI_STATUS
881 EFIAPI
882 AhciNonDataTransfer (
883 IN EFI_PCI_IO_PROTOCOL *PciIo,
884 IN EFI_AHCI_REGISTERS *AhciRegisters,
885 IN UINT8 Port,
886 IN UINT8 PortMultiplier,
887 IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
888 IN UINT8 AtapiCommandLength,
889 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
890 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
891 IN UINT64 Timeout
892 )
893 {
894 EFI_STATUS Status;
895 UINTN FisBaseAddr;
896 UINT32 Offset;
897 UINT32 Value;
898 UINT32 Delay;
899
900 EFI_AHCI_COMMAND_FIS CFis;
901 EFI_AHCI_COMMAND_LIST CmdList;
902
903 //
904 // Package read needed
905 //
906 AhciBuildCommandFis (&CFis, AtaCommandBlock);
907
908 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
909
910 CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;
911
912 AhciBuildCommand (
913 PciIo,
914 AhciRegisters,
915 Port,
916 PortMultiplier,
917 &CFis,
918 &CmdList,
919 AtapiCommand,
920 AtapiCommandLength,
921 0,
922 NULL,
923 0
924 );
925
926 Status = AhciStartCommand (
927 PciIo,
928 Port,
929 0,
930 Timeout
931 );
932 if (EFI_ERROR (Status)) {
933 goto Exit;
934 }
935
936 //
937 // Wait device sends the Response Fis
938 //
939 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
940 //
941 // Wait device sends the PIO setup fis before data transfer
942 //
943 Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
944 do {
945 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
946
947 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
948 break;
949 }
950
951 //
952 // Stall for 100 microseconds.
953 //
954 MicroSecondDelay(100);
955
956 Delay --;
957 } while (Delay > 0);
958
959 if (Delay == 0) {
960 Status = EFI_TIMEOUT;
961 goto Exit;
962 }
963
964 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
965
966 Status = AhciWaitMemSet (
967 PciIo,
968 Offset,
969 0xFFFFFFFF,
970 0,
971 Timeout
972 );
973
974 Exit:
975 AhciStopCommand (
976 PciIo,
977 Port,
978 Timeout
979 );
980
981 AhciDisableFisReceive (
982 PciIo,
983 Port,
984 Timeout
985 );
986
987 return Status;
988 }
989
990 /**
991 Stop command running for giving port
992
993 @param PciIo The PCI IO protocol instance.
994 @param Port The number of port.
995 @param Timeout The timeout value of stop.
996
997 @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
998 @retval EFI_TIMEOUT The operation is time out.
999 @retval EFI_SUCCESS The command stop successfully.
1000
1001 **/
1002 EFI_STATUS
1003 EFIAPI
1004 AhciStopCommand (
1005 IN EFI_PCI_IO_PROTOCOL *PciIo,
1006 IN UINT8 Port,
1007 IN UINT64 Timeout
1008 )
1009 {
1010 UINT32 Offset;
1011 UINT32 Data;
1012
1013 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1014 Data = AhciReadReg (PciIo, Offset);
1015
1016 if ((Data & (EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_CR)) == 0) {
1017 return EFI_SUCCESS;
1018 }
1019
1020 if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {
1021 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));
1022 }
1023
1024 return AhciWaitMemSet (
1025 PciIo,
1026 Offset,
1027 EFI_AHCI_PORT_CMD_CR,
1028 0,
1029 Timeout
1030 );
1031 }
1032
1033 /**
1034 Start command for give slot on specific port.
1035
1036 @param PciIo The PCI IO protocol instance.
1037 @param Port The number of port.
1038 @param CommandSlot The number of CommandSlot.
1039 @param Timeout The timeout value of start.
1040
1041 @retval EFI_DEVICE_ERROR The command start unsuccessfully.
1042 @retval EFI_TIMEOUT The operation is time out.
1043 @retval EFI_SUCCESS The command start successfully.
1044
1045 **/
1046 EFI_STATUS
1047 EFIAPI
1048 AhciStartCommand (
1049 IN EFI_PCI_IO_PROTOCOL *PciIo,
1050 IN UINT8 Port,
1051 IN UINT8 CommandSlot,
1052 IN UINT64 Timeout
1053 )
1054 {
1055 UINT32 CmdSlotBit;
1056 EFI_STATUS Status;
1057 UINT32 PortStatus;
1058 UINT32 StartCmd;
1059 UINT32 PortTfd;
1060 UINT32 Offset;
1061 UINT32 Capability;
1062
1063 //
1064 // Collect AHCI controller information
1065 //
1066 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1067
1068 CmdSlotBit = (UINT32) (1 << CommandSlot);
1069
1070 AhciClearPortStatus (
1071 PciIo,
1072 Port
1073 );
1074
1075 Status = AhciEnableFisReceive (
1076 PciIo,
1077 Port,
1078 Timeout
1079 );
1080
1081 if (EFI_ERROR (Status)) {
1082 return Status;
1083 }
1084
1085 //
1086 // Setting the command
1087 //
1088 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SACT;
1089 AhciAndReg (PciIo, Offset, 0);
1090 AhciOrReg (PciIo, Offset, CmdSlotBit);
1091
1092 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;
1093 AhciAndReg (PciIo, Offset, 0);
1094 AhciOrReg (PciIo, Offset, CmdSlotBit);
1095
1096 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1097 PortStatus = AhciReadReg (PciIo, Offset);
1098
1099 StartCmd = 0;
1100 if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {
1101 StartCmd = AhciReadReg (PciIo, Offset);
1102 StartCmd &= ~EFI_AHCI_PORT_CMD_ICC_MASK;
1103 StartCmd |= EFI_AHCI_PORT_CMD_ACTIVE;
1104 }
1105
1106 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;
1107 PortTfd = AhciReadReg (PciIo, Offset);
1108
1109 if ((PortTfd & (EFI_AHCI_PORT_TFD_BSY | EFI_AHCI_PORT_TFD_DRQ)) != 0) {
1110 if ((Capability & BIT24) != 0) {
1111 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1112 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_COL);
1113
1114 AhciWaitMemSet (
1115 PciIo,
1116 Offset,
1117 EFI_AHCI_PORT_CMD_COL,
1118 0,
1119 Timeout
1120 );
1121 }
1122 }
1123
1124 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
1125 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_ST | StartCmd);
1126
1127 return EFI_SUCCESS;
1128 }
1129
1130 /**
1131 Do AHCI port reset.
1132
1133 @param PciIo The PCI IO protocol instance.
1134 @param Port The number of port.
1135 @param Timeout The timeout value of reset.
1136
1137 @retval EFI_DEVICE_ERROR The port reset unsuccessfully
1138 @retval EFI_TIMEOUT The reset operation is time out.
1139 @retval EFI_SUCCESS The port reset successfully.
1140
1141 **/
1142 EFI_STATUS
1143 EFIAPI
1144 AhciPortReset (
1145 IN EFI_PCI_IO_PROTOCOL *PciIo,
1146 IN UINT8 Port,
1147 IN UINT64 Timeout
1148 )
1149 {
1150 EFI_STATUS Status;
1151 UINT32 Offset;
1152
1153 AhciClearPortStatus (PciIo, Port);
1154
1155 AhciStopCommand (PciIo, Port, Timeout);
1156
1157 AhciDisableFisReceive (PciIo, Port, Timeout);
1158
1159 AhciEnableFisReceive (PciIo, Port, Timeout);
1160
1161 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
1162
1163 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);
1164
1165 //
1166 // wait 5 milliseceond before de-assert DET
1167 //
1168 MicroSecondDelay (5000);
1169
1170 AhciAndReg (PciIo, Offset, (UINT32)EFI_AHCI_PORT_SCTL_MASK);
1171
1172 //
1173 // wait 5 milliseceond before de-assert DET
1174 //
1175 MicroSecondDelay (5000);
1176
1177 //
1178 // Wait for communication to be re-established
1179 //
1180 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
1181 Status = AhciWaitMemSet (
1182 PciIo,
1183 Offset,
1184 EFI_AHCI_PORT_SSTS_DET_MASK,
1185 EFI_AHCI_PORT_SSTS_DET_PCE,
1186 Timeout
1187 );
1188
1189 if (EFI_ERROR (Status)) {
1190 return Status;
1191 }
1192
1193 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
1194 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_ERR_CLEAR);
1195
1196 return EFI_SUCCESS;
1197 }
1198
1199 /**
1200 Do AHCI HBA reset.
1201
1202 @param PciIo The PCI IO protocol instance.
1203 @param Timeout The timeout value of reset.
1204
1205
1206 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
1207 @retval EFI_TIMEOUT The reset operation is time out.
1208 @retval EFI_SUCCESS AHCI controller is reset successfully.
1209
1210 **/
1211 EFI_STATUS
1212 EFIAPI
1213 AhciReset (
1214 IN EFI_PCI_IO_PROTOCOL *PciIo,
1215 IN UINT64 Timeout
1216 )
1217 {
1218 EFI_STATUS Status;
1219 UINT32 Delay;
1220 UINT32 Value;
1221
1222 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
1223
1224 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);
1225
1226 Status = EFI_TIMEOUT;
1227
1228 Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);
1229
1230 do {
1231 Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);
1232
1233 if ((Value & EFI_AHCI_GHC_RESET) == 0) {
1234 break;
1235 }
1236
1237 //
1238 // Stall for 100 microseconds.
1239 //
1240 MicroSecondDelay(100);
1241
1242 Delay--;
1243 } while (Delay > 0);
1244
1245 if (Delay == 0) {
1246 return EFI_TIMEOUT;
1247 }
1248
1249 return EFI_SUCCESS;
1250 }
1251
1252 /**
1253 Send SMART Return Status command to check if the execution of SMART cmd is successful or not.
1254
1255 @param PciIo The PCI IO protocol instance.
1256 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1257 @param Port The number of port.
1258 @param PortMultiplier The timeout value of stop.
1259 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1260
1261 @retval EFI_SUCCESS Successfully get the return status of S.M.A.R.T command execution.
1262 @retval Others Fail to get return status data.
1263
1264 **/
1265 EFI_STATUS
1266 EFIAPI
1267 AhciAtaSmartReturnStatusCheck (
1268 IN EFI_PCI_IO_PROTOCOL *PciIo,
1269 IN EFI_AHCI_REGISTERS *AhciRegisters,
1270 IN UINT8 Port,
1271 IN UINT8 PortMultiplier,
1272 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1273 )
1274 {
1275 EFI_STATUS Status;
1276 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1277 UINT8 LBAMid;
1278 UINT8 LBAHigh;
1279 UINTN FisBaseAddr;
1280 UINT32 Value;
1281
1282 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1283
1284 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1285 AtaCommandBlock.AtaFeatures = ATA_SMART_RETURN_STATUS;
1286 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1287 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1288
1289 //
1290 // Send S.M.A.R.T Read Return Status command to device
1291 //
1292 Status = AhciNonDataTransfer (
1293 PciIo,
1294 AhciRegisters,
1295 (UINT8)Port,
1296 (UINT8)PortMultiplier,
1297 NULL,
1298 0,
1299 &AtaCommandBlock,
1300 AtaStatusBlock,
1301 ATA_ATAPI_TIMEOUT
1302 );
1303
1304 if (EFI_ERROR (Status)) {
1305 return EFI_DEVICE_ERROR;
1306 }
1307
1308 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);
1309
1310 Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
1311
1312 if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {
1313 LBAMid = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[5];
1314 LBAHigh = ((UINT8 *)(UINTN)(FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET))[6];
1315
1316 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
1317 //
1318 // The threshold exceeded condition is not detected by the device
1319 //
1320 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));
1321
1322 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
1323 //
1324 // The threshold exceeded condition is detected by the device
1325 //
1326 DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));
1327 }
1328 }
1329
1330 return EFI_SUCCESS;
1331 }
1332
1333 /**
1334 Enable SMART command of the disk if supported.
1335
1336 @param PciIo The PCI IO protocol instance.
1337 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1338 @param Port The number of port.
1339 @param PortMultiplier The timeout value of stop.
1340 @param IdentifyData A pointer to data buffer which is used to contain IDENTIFY data.
1341 @param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
1342
1343 **/
1344 VOID
1345 EFIAPI
1346 AhciAtaSmartSupport (
1347 IN EFI_PCI_IO_PROTOCOL *PciIo,
1348 IN EFI_AHCI_REGISTERS *AhciRegisters,
1349 IN UINT8 Port,
1350 IN UINT8 PortMultiplier,
1351 IN EFI_IDENTIFY_DATA *IdentifyData,
1352 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock
1353 )
1354 {
1355 EFI_STATUS Status;
1356 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1357
1358 //
1359 // Detect if the device supports S.M.A.R.T.
1360 //
1361 if ((IdentifyData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
1362 //
1363 // S.M.A.R.T is not supported by the device
1364 //
1365 DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at port [%d] PortMultiplier [%d]!\n",
1366 Port, PortMultiplier));
1367 } else {
1368 //
1369 // Check if the feature is enabled. If not, then enable S.M.A.R.T.
1370 //
1371 if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {
1372 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1373
1374 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1375 AtaCommandBlock.AtaFeatures = ATA_SMART_ENABLE_OPERATION;
1376 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1377 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1378
1379 //
1380 // Send S.M.A.R.T Enable command to device
1381 //
1382 Status = AhciNonDataTransfer (
1383 PciIo,
1384 AhciRegisters,
1385 (UINT8)Port,
1386 (UINT8)PortMultiplier,
1387 NULL,
1388 0,
1389 &AtaCommandBlock,
1390 AtaStatusBlock,
1391 ATA_ATAPI_TIMEOUT
1392 );
1393
1394
1395 if (!EFI_ERROR (Status)) {
1396 //
1397 // Send S.M.A.R.T AutoSave command to device
1398 //
1399 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1400
1401 AtaCommandBlock.AtaCommand = ATA_CMD_SMART;
1402 AtaCommandBlock.AtaFeatures = 0xD2;
1403 AtaCommandBlock.AtaSectorCount = 0xF1;
1404 AtaCommandBlock.AtaCylinderLow = ATA_CONSTANT_4F;
1405 AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;
1406
1407 Status = AhciNonDataTransfer (
1408 PciIo,
1409 AhciRegisters,
1410 (UINT8)Port,
1411 (UINT8)PortMultiplier,
1412 NULL,
1413 0,
1414 &AtaCommandBlock,
1415 AtaStatusBlock,
1416 ATA_ATAPI_TIMEOUT
1417 );
1418
1419 if (!EFI_ERROR (Status)) {
1420 Status = AhciAtaSmartReturnStatusCheck (
1421 PciIo,
1422 AhciRegisters,
1423 (UINT8)Port,
1424 (UINT8)PortMultiplier,
1425 AtaStatusBlock
1426 );
1427 }
1428 }
1429 }
1430 DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",
1431 Port, PortMultiplier));
1432 }
1433
1434 return ;
1435 }
1436
1437 /**
1438 Send Buffer cmd to specific device.
1439
1440 @param PciIo The PCI IO protocol instance.
1441 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1442 @param Port The number of port.
1443 @param PortMultiplier The timeout value of stop.
1444 @param Buffer The data buffer to store IDENTIFY PACKET data.
1445
1446 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1447 @retval EFI_TIMEOUT The operation is time out.
1448 @retval EFI_UNSUPPORTED The device is not ready for executing.
1449 @retval EFI_SUCCESS The cmd executes successfully.
1450
1451 **/
1452 EFI_STATUS
1453 EFIAPI
1454 AhciIdentify (
1455 IN EFI_PCI_IO_PROTOCOL *PciIo,
1456 IN EFI_AHCI_REGISTERS *AhciRegisters,
1457 IN UINT8 Port,
1458 IN UINT8 PortMultiplier,
1459 IN OUT EFI_IDENTIFY_DATA *Buffer
1460 )
1461 {
1462 EFI_STATUS Status;
1463 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1464 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1465
1466 if (PciIo == NULL || AhciRegisters == NULL || Buffer == NULL) {
1467 return EFI_INVALID_PARAMETER;
1468 }
1469
1470 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1471 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1472
1473 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1474 AtaCommandBlock.AtaSectorCount = 1;
1475
1476 Status = AhciPioTransfer (
1477 PciIo,
1478 AhciRegisters,
1479 Port,
1480 PortMultiplier,
1481 NULL,
1482 0,
1483 TRUE,
1484 &AtaCommandBlock,
1485 &AtaStatusBlock,
1486 Buffer,
1487 sizeof (EFI_IDENTIFY_DATA),
1488 ATA_ATAPI_TIMEOUT
1489 );
1490
1491 return Status;
1492 }
1493
1494 /**
1495 Send Buffer cmd to specific device.
1496
1497 @param PciIo The PCI IO protocol instance.
1498 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1499 @param Port The number of port.
1500 @param PortMultiplier The timeout value of stop.
1501 @param Buffer The data buffer to store IDENTIFY PACKET data.
1502
1503 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1504 @retval EFI_TIMEOUT The operation is time out.
1505 @retval EFI_UNSUPPORTED The device is not ready for executing.
1506 @retval EFI_SUCCESS The cmd executes successfully.
1507
1508 **/
1509 EFI_STATUS
1510 EFIAPI
1511 AhciIdentifyPacket (
1512 IN EFI_PCI_IO_PROTOCOL *PciIo,
1513 IN EFI_AHCI_REGISTERS *AhciRegisters,
1514 IN UINT8 Port,
1515 IN UINT8 PortMultiplier,
1516 IN OUT EFI_IDENTIFY_DATA *Buffer
1517 )
1518 {
1519 EFI_STATUS Status;
1520 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1521 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1522
1523 if (PciIo == NULL || AhciRegisters == NULL) {
1524 return EFI_INVALID_PARAMETER;
1525 }
1526
1527 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1528 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1529
1530 AtaCommandBlock.AtaCommand = ATA_CMD_IDENTIFY_DEVICE;
1531 AtaCommandBlock.AtaSectorCount = 1;
1532
1533 Status = AhciPioTransfer (
1534 PciIo,
1535 AhciRegisters,
1536 Port,
1537 PortMultiplier,
1538 NULL,
1539 0,
1540 TRUE,
1541 &AtaCommandBlock,
1542 &AtaStatusBlock,
1543 Buffer,
1544 sizeof (EFI_IDENTIFY_DATA),
1545 ATA_ATAPI_TIMEOUT
1546 );
1547
1548 return Status;
1549 }
1550
1551 /**
1552 Send SET FEATURE cmd on specific device.
1553
1554 @param PciIo The PCI IO protocol instance.
1555 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1556 @param Port The number of port.
1557 @param PortMultiplier The timeout value of stop.
1558 @param Feature The data to send Feature register.
1559 @param FeatureSpecificData The specific data for SET FEATURE cmd.
1560
1561 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1562 @retval EFI_TIMEOUT The operation is time out.
1563 @retval EFI_UNSUPPORTED The device is not ready for executing.
1564 @retval EFI_SUCCESS The cmd executes successfully.
1565
1566 **/
1567 EFI_STATUS
1568 EFIAPI
1569 AhciDeviceSetFeature (
1570 IN EFI_PCI_IO_PROTOCOL *PciIo,
1571 IN EFI_AHCI_REGISTERS *AhciRegisters,
1572 IN UINT8 Port,
1573 IN UINT8 PortMultiplier,
1574 IN UINT16 Feature,
1575 IN UINT32 FeatureSpecificData
1576 )
1577 {
1578 EFI_STATUS Status;
1579 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1580 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1581
1582 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1583 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1584
1585 AtaCommandBlock.AtaCommand = ATA_CMD_SET_FEATURES;
1586 AtaCommandBlock.AtaFeatures = (UINT8) Feature;
1587 AtaCommandBlock.AtaFeaturesExp = (UINT8) (Feature >> 8);
1588 AtaCommandBlock.AtaSectorCount = (UINT8) FeatureSpecificData;
1589 AtaCommandBlock.AtaSectorNumber = (UINT8) (FeatureSpecificData >> 8);
1590 AtaCommandBlock.AtaCylinderLow = (UINT8) (FeatureSpecificData >> 16);
1591 AtaCommandBlock.AtaCylinderHigh = (UINT8) (FeatureSpecificData >> 24);
1592
1593 Status = AhciNonDataTransfer (
1594 PciIo,
1595 AhciRegisters,
1596 (UINT8)Port,
1597 (UINT8)PortMultiplier,
1598 NULL,
1599 0,
1600 &AtaCommandBlock,
1601 &AtaStatusBlock,
1602 ATA_ATAPI_TIMEOUT
1603 );
1604
1605 return Status;
1606 }
1607
1608 /**
1609 This function is used to send out ATAPI commands conforms to the Packet Command
1610 with PIO Protocol.
1611
1612 @param PciIo The PCI IO protocol instance.
1613 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1614 @param Port The number of port.
1615 @param PortMultiplier The number of port multiplier.
1616 @param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
1617
1618 @retval EFI_SUCCESS send out the ATAPI packet command successfully
1619 and device sends data successfully.
1620 @retval EFI_DEVICE_ERROR the device failed to send data.
1621
1622 **/
1623 EFI_STATUS
1624 EFIAPI
1625 AhciPacketCommandExecute (
1626 IN EFI_PCI_IO_PROTOCOL *PciIo,
1627 IN EFI_AHCI_REGISTERS *AhciRegisters,
1628 IN UINT8 Port,
1629 IN UINT8 PortMultiplier,
1630 IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
1631 )
1632 {
1633 EFI_STATUS Status;
1634 VOID *Buffer;
1635 UINT32 Length;
1636 EFI_ATA_COMMAND_BLOCK AtaCommandBlock;
1637 EFI_ATA_STATUS_BLOCK AtaStatusBlock;
1638 BOOLEAN Read;
1639 UINT8 Retry;
1640
1641 if (Packet == NULL || Packet->Cdb == NULL) {
1642 return EFI_INVALID_PARAMETER;
1643 }
1644
1645 ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));
1646 ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));
1647 AtaCommandBlock.AtaCommand = ATA_CMD_PACKET;
1648 //
1649 // No OVL; No DMA
1650 //
1651 AtaCommandBlock.AtaFeatures = 0x00;
1652 //
1653 // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
1654 // determine how many data should be transferred.
1655 //
1656 AtaCommandBlock.AtaCylinderLow = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);
1657 AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);
1658
1659 if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
1660 Buffer = Packet->InDataBuffer;
1661 Length = Packet->InTransferLength;
1662 Read = TRUE;
1663 } else {
1664 Buffer = Packet->OutDataBuffer;
1665 Length = Packet->OutTransferLength;
1666 Read = FALSE;
1667 }
1668
1669 if (Length == 0) {
1670 Status = AhciNonDataTransfer (
1671 PciIo,
1672 AhciRegisters,
1673 Port,
1674 PortMultiplier,
1675 Packet->Cdb,
1676 Packet->CdbLength,
1677 &AtaCommandBlock,
1678 &AtaStatusBlock,
1679 Packet->Timeout
1680 );
1681 } else {
1682 //
1683 // READ_CAPACITY cmd may execute failure. Retry 5 times
1684 //
1685 if (((UINT8 *)Packet->Cdb)[0] == ATA_CMD_READ_CAPACITY) {
1686 Retry = 5;
1687 } else {
1688 Retry = 1;
1689 }
1690 do {
1691 Status = AhciPioTransfer (
1692 PciIo,
1693 AhciRegisters,
1694 Port,
1695 PortMultiplier,
1696 Packet->Cdb,
1697 Packet->CdbLength,
1698 Read,
1699 &AtaCommandBlock,
1700 &AtaStatusBlock,
1701 Buffer,
1702 Length,
1703 Packet->Timeout
1704 );
1705 if (!EFI_ERROR (Status)) {
1706 break;
1707 }
1708 Retry--;
1709 } while (Retry != 0);
1710 }
1711 return Status;
1712 }
1713
1714 /**
1715 Allocate transfer-related data struct which is used at AHCI mode.
1716
1717 @param PciIo The PCI IO protocol instance.
1718 @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
1719
1720 **/
1721 EFI_STATUS
1722 EFIAPI
1723 AhciCreateTransferDescriptor (
1724 IN EFI_PCI_IO_PROTOCOL *PciIo,
1725 IN OUT EFI_AHCI_REGISTERS *AhciRegisters
1726 )
1727 {
1728 EFI_STATUS Status;
1729 UINTN Bytes;
1730 VOID *Buffer;
1731
1732 UINT32 Capability;
1733 UINT8 MaxPortNumber;
1734 UINT8 MaxCommandSlotNumber;
1735 BOOLEAN Support64Bit;
1736 UINT64 MaxReceiveFisSize;
1737 UINT64 MaxCommandListSize;
1738 UINT64 MaxCommandTableSize;
1739
1740 Buffer = NULL;
1741 //
1742 // Collect AHCI controller information
1743 //
1744 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
1745 MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1);
1746 //
1747 // Get the number of command slots per port supported by this HBA.
1748 //
1749 MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1);
1750 Support64Bit = (BOOLEAN) (((Capability & BIT31) != 0) ? TRUE : FALSE);
1751
1752 MaxReceiveFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
1753 Status = PciIo->AllocateBuffer (
1754 PciIo,
1755 AllocateAnyPages,
1756 EfiBootServicesData,
1757 (UINTN)EFI_SIZE_TO_PAGES (MaxReceiveFisSize),
1758 &Buffer,
1759 0
1760 );
1761
1762 if (EFI_ERROR (Status)) {
1763 return EFI_OUT_OF_RESOURCES;
1764 }
1765
1766 ZeroMem (Buffer, (UINTN)MaxReceiveFisSize);
1767
1768 AhciRegisters->AhciRFis = Buffer;
1769 AhciRegisters->MaxReceiveFisSize = MaxReceiveFisSize;
1770 Bytes = (UINTN)MaxReceiveFisSize;
1771
1772 Status = PciIo->Map (
1773 PciIo,
1774 EfiPciIoOperationBusMasterCommonBuffer,
1775 Buffer,
1776 &Bytes,
1777 (EFI_PHYSICAL_ADDRESS *) &AhciRegisters->AhciRFisPciAddr,
1778 &AhciRegisters->MapRFis
1779 );
1780
1781 if (EFI_ERROR (Status) || (Bytes != MaxReceiveFisSize)) {
1782 //
1783 // Map error or unable to map the whole RFis buffer into a contiguous region.
1784 //
1785 Status = EFI_OUT_OF_RESOURCES;
1786 goto Error6;
1787 }
1788
1789 if ((!Support64Bit) && ((EFI_PHYSICAL_ADDRESS)(UINTN)AhciRegisters->AhciRFisPciAddr > 0x100000000ULL)) {
1790 //
1791 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
1792 //
1793 Status = EFI_DEVICE_ERROR;
1794 goto Error5;
1795 }
1796
1797 //
1798 // Allocate memory for command list
1799 // Note that the implemenation is a single task model which only use a command list for all ports.
1800 //
1801 Buffer = NULL;
1802 MaxCommandListSize = MaxCommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST);
1803 Status = PciIo->AllocateBuffer (
1804 PciIo,
1805 AllocateAnyPages,
1806 EfiBootServicesData,
1807 (UINTN)EFI_SIZE_TO_PAGES (MaxCommandListSize),
1808 &Buffer,
1809 0
1810 );
1811
1812 if (EFI_ERROR (Status)) {
1813 //
1814 // Free mapped resource.
1815 //
1816 Status = EFI_OUT_OF_RESOURCES;
1817 goto Error5;
1818 }
1819
1820 ZeroMem (Buffer, (UINTN)MaxCommandListSize);
1821
1822 AhciRegisters->AhciCmdList = Buffer;
1823 AhciRegisters->MaxCommandListSize = MaxCommandListSize;
1824 Bytes = (UINTN)MaxCommandListSize;
1825
1826 Status = PciIo->Map (
1827 PciIo,
1828 EfiPciIoOperationBusMasterCommonBuffer,
1829 Buffer,
1830 &Bytes,
1831 (EFI_PHYSICAL_ADDRESS *)&AhciRegisters->AhciCmdListPciAddr,
1832 &AhciRegisters->MapCmdList
1833 );
1834
1835 if (EFI_ERROR (Status) || (Bytes != MaxCommandListSize)) {
1836 //
1837 // Map error or unable to map the whole cmd list buffer into a contiguous region.
1838 //
1839 Status = EFI_OUT_OF_RESOURCES;
1840 goto Error4;
1841 }
1842
1843 if ((!Support64Bit) && ((EFI_PHYSICAL_ADDRESS)(UINTN)AhciRegisters->AhciCmdListPciAddr > 0x100000000ULL)) {
1844 //
1845 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
1846 //
1847 Status = EFI_DEVICE_ERROR;
1848 goto Error3;
1849 }
1850
1851 //
1852 // Allocate memory for command table
1853 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
1854 //
1855 Buffer = NULL;
1856 MaxCommandTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
1857
1858 Status = PciIo->AllocateBuffer (
1859 PciIo,
1860 AllocateAnyPages,
1861 EfiBootServicesData,
1862 (UINTN)EFI_SIZE_TO_PAGES (MaxCommandTableSize),
1863 &Buffer,
1864 0
1865 );
1866
1867 if (EFI_ERROR (Status)) {
1868 //
1869 // Free mapped resource.
1870 //
1871 Status = EFI_OUT_OF_RESOURCES;
1872 goto Error3;
1873 }
1874
1875 ZeroMem (Buffer, (UINTN)MaxCommandTableSize);
1876
1877 AhciRegisters->AhciCommandTable = Buffer;
1878 AhciRegisters->MaxCommandTableSize = MaxCommandTableSize;
1879 Bytes = (UINTN)MaxCommandTableSize;
1880
1881 Status = PciIo->Map (
1882 PciIo,
1883 EfiPciIoOperationBusMasterCommonBuffer,
1884 Buffer,
1885 &Bytes,
1886 (EFI_PHYSICAL_ADDRESS *)&AhciRegisters->AhciCommandTablePciAddr,
1887 &AhciRegisters->MapCommandTable
1888 );
1889
1890 if (EFI_ERROR (Status) || (Bytes != MaxCommandTableSize)) {
1891 //
1892 // Map error or unable to map the whole cmd list buffer into a contiguous region.
1893 //
1894 Status = EFI_OUT_OF_RESOURCES;
1895 goto Error2;
1896 }
1897
1898 if ((!Support64Bit) && ((EFI_PHYSICAL_ADDRESS)(UINTN)AhciRegisters->AhciCommandTablePciAddr > 0x100000000ULL)) {
1899 //
1900 // The AHCI HBA doesn't support 64bit addressing, so should not get a >4G pci bus master address.
1901 //
1902 Status = EFI_DEVICE_ERROR;
1903 goto Error1;
1904 }
1905
1906 return EFI_SUCCESS;
1907 //
1908 // Map error or unable to map the whole CmdList buffer into a contiguous region.
1909 //
1910 Error1:
1911 PciIo->Unmap (
1912 PciIo,
1913 AhciRegisters->MapCommandTable
1914 );
1915 Error2:
1916 PciIo->FreeBuffer (
1917 PciIo,
1918 (UINTN)EFI_SIZE_TO_PAGES (MaxCommandTableSize),
1919 AhciRegisters->AhciCommandTable
1920 );
1921 Error3:
1922 PciIo->Unmap (
1923 PciIo,
1924 AhciRegisters->MapCmdList
1925 );
1926 Error4:
1927 PciIo->FreeBuffer (
1928 PciIo,
1929 (UINTN)EFI_SIZE_TO_PAGES (MaxCommandListSize),
1930 AhciRegisters->AhciCmdList
1931 );
1932 Error5:
1933 PciIo->Unmap (
1934 PciIo,
1935 AhciRegisters->MapRFis
1936 );
1937 Error6:
1938 PciIo->FreeBuffer (
1939 PciIo,
1940 (UINTN)EFI_SIZE_TO_PAGES (MaxReceiveFisSize),
1941 AhciRegisters->AhciRFis
1942 );
1943
1944 return Status;
1945 }
1946
1947 /**
1948 Initialize ATA host controller at AHCI mode.
1949
1950 The function is designed to initialize ATA host controller.
1951
1952 @param[in] Instance A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
1953
1954 **/
1955 EFI_STATUS
1956 EFIAPI
1957 AhciModeInitialization (
1958 IN ATA_ATAPI_PASS_THRU_INSTANCE *Instance
1959 )
1960 {
1961 EFI_STATUS Status;
1962 EFI_PCI_IO_PROTOCOL *PciIo;
1963 EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeInit;
1964 UINT32 Capability;
1965 UINT8 MaxPortNumber;
1966 UINT32 PortImplementBitMap;
1967 UINT8 MaxCommandSlotNumber;
1968 BOOLEAN Support64Bit;
1969
1970 EFI_AHCI_REGISTERS *AhciRegisters;
1971
1972 UINT8 Port;
1973 DATA_64 Data64;
1974 UINT32 Offset;
1975 UINT32 Data;
1976 EFI_IDENTIFY_DATA Buffer;
1977 EFI_ATA_DEVICE_TYPE DeviceType;
1978 EFI_ATA_COLLECTIVE_MODE *SupportedModes;
1979 EFI_ATA_TRANSFER_MODE TransferMode;
1980
1981 if (Instance == NULL) {
1982 return EFI_INVALID_PARAMETER;
1983 }
1984
1985 PciIo = Instance->PciIo;
1986 IdeInit = Instance->IdeControllerInit;
1987
1988 Status = AhciReset (PciIo, ATA_ATAPI_TIMEOUT);
1989
1990 if (EFI_ERROR (Status)) {
1991 return EFI_DEVICE_ERROR;
1992 }
1993
1994 //
1995 // Enable AE before accessing any AHCI registers
1996 //
1997 AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);
1998
1999 //
2000 // Collect AHCI controller information
2001 //
2002 Capability = AhciReadReg(PciIo, EFI_AHCI_CAPABILITY_OFFSET);
2003
2004 //
2005 // Get the number of command slots per port supported by this HBA.
2006 //
2007 MaxCommandSlotNumber = (UINT8) (((Capability & 0x1F00) >> 8) + 1);
2008 Support64Bit = (BOOLEAN) (((Capability & BIT31) != 0) ? TRUE : FALSE);
2009
2010 //
2011 // Get the bit map of those ports exposed by this HBA.
2012 // It indicates which ports that the HBA supports are available for software to use.
2013 //
2014 PortImplementBitMap = AhciReadReg(PciIo, EFI_AHCI_PI_OFFSET);
2015 MaxPortNumber = (UINT8) ((Capability & 0x1F) + 1);
2016
2017 AhciRegisters = &Instance->AhciRegisters;
2018 Status = AhciCreateTransferDescriptor (PciIo, AhciRegisters);
2019
2020 if (EFI_ERROR (Status)) {
2021 return EFI_OUT_OF_RESOURCES;
2022 }
2023
2024 for (Port = 0; Port < MaxPortNumber; Port ++) {
2025 Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFisPciAddr) + sizeof (EFI_AHCI_RECEIVED_FIS) * Port;
2026
2027 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FB;
2028 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2029 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_FBU;
2030 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2031
2032 //
2033 // Single task envrionment, we only use one command table for all port
2034 //
2035 Data64.Uint64 = (UINTN) (AhciRegisters->AhciCmdListPciAddr);
2036
2037 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLB;
2038 AhciWriteReg (PciIo, Offset, Data64.Uint32.Lower32);
2039 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CLBU;
2040 AhciWriteReg (PciIo, Offset, Data64.Uint32.Upper32);
2041
2042 if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
2043 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;
2044
2045 if ((Capability & EFI_AHCI_PORT_CMD_ASP) != 0) {
2046 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_SUD);
2047 }
2048 Data = AhciReadReg (PciIo, Offset);
2049 if ((Data & EFI_AHCI_PORT_CMD_CPD) != 0) {
2050 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_POD);
2051 }
2052
2053 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE|EFI_AHCI_PORT_CMD_COL|EFI_AHCI_PORT_CMD_ST));
2054 }
2055
2056 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SCTL;
2057 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_SCTL_IPM_MASK));
2058
2059 AhciAndReg (PciIo, Offset,(UINT32) ~(EFI_AHCI_PORT_SCTL_IPM_PSD));
2060 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_PSD);
2061
2062 AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_SCTL_IPM_SSD));
2063 AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_IPM_SSD);
2064
2065 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IE;
2066 AhciAndReg (PciIo, Offset, 0);
2067
2068 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;
2069 AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));
2070 }
2071
2072 //
2073 // Stall for 100 milliseconds.
2074 //
2075 MicroSecondDelay(100000);
2076
2077 IdeInit->NotifyPhase (IdeInit, EfiIdeBeforeChannelEnumeration, Port);
2078
2079 for (Port = 0; Port < MaxPortNumber; Port ++) {
2080 if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
2081
2082 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;
2083 Data = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;
2084
2085 if (Data == 0) {
2086 continue;
2087 }
2088 //
2089 // Found device in the port
2090 //
2091 if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) {
2092 Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;
2093
2094 Status = AhciWaitMemSet (
2095 PciIo,
2096 Offset,
2097 0x0000FFFF,
2098 0x00000101,
2099 ATA_ATAPI_TIMEOUT
2100 );
2101 if (EFI_ERROR (Status)) {
2102 continue;
2103 }
2104
2105 //
2106 // Now inform the IDE Controller Init Module.
2107 //
2108 IdeInit->NotifyPhase (IdeInit, EfiIdeBusBeforeDevicePresenceDetection, Port);
2109
2110 Data = AhciReadReg (PciIo, Offset);
2111
2112 if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATAPI_DEVICE_SIG) {
2113 Status = AhciIdentifyPacket (PciIo, AhciRegisters, Port, 0, &Buffer);
2114
2115 if (EFI_ERROR (Status)) {
2116 continue;
2117 }
2118
2119 DeviceType = EfiIdeCdrom;
2120 } else if ((Data & EFI_AHCI_ATAPI_SIG_MASK) == EFI_AHCI_ATA_DEVICE_SIG) {
2121 Status = AhciIdentify (PciIo, AhciRegisters, Port, 0, &Buffer);
2122
2123 if (EFI_ERROR (Status)) {
2124 continue;
2125 }
2126
2127 DeviceType = EfiIdeHarddisk;
2128 } else {
2129 continue;
2130 }
2131
2132 DEBUG ((EFI_D_INFO, "port [%d] port mulitplier [%d] has a [%a]\n",
2133 Port, 0, DeviceType == EfiIdeCdrom ? "cdrom" : "harddisk"));
2134
2135 //
2136 // If the device is a hard disk, then try to enable S.M.A.R.T feature
2137 //
2138 if (DeviceType == EfiIdeHarddisk) {
2139 AhciAtaSmartSupport (
2140 PciIo,
2141 AhciRegisters,
2142 Port,
2143 0,
2144 &Buffer,
2145 NULL
2146 );
2147 }
2148
2149 //
2150 // Submit identify data to IDE controller init driver
2151 //
2152 IdeInit->SubmitData (IdeInit, Port, 0, &Buffer);
2153
2154 //
2155 // Now start to config ide device parameter and transfer mode.
2156 //
2157 Status = IdeInit->CalculateMode (
2158 IdeInit,
2159 Port,
2160 0,
2161 &SupportedModes
2162 );
2163 if (EFI_ERROR (Status)) {
2164 DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));
2165 continue;
2166 }
2167
2168 //
2169 // Set best supported PIO mode on this IDE device
2170 //
2171 if (SupportedModes->PioMode.Mode <= EfiAtaPioMode2) {
2172 TransferMode.ModeCategory = EFI_ATA_MODE_DEFAULT_PIO;
2173 } else {
2174 TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;
2175 }
2176
2177 TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);
2178
2179 //
2180 // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't
2181 // be set together. Only one DMA mode can be set to a device. If setting
2182 // DMA mode operation fails, we can continue moving on because we only use
2183 // PIO mode at boot time. DMA modes are used by certain kind of OS booting
2184 //
2185 if (SupportedModes->UdmaMode.Valid) {
2186 TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;
2187 TransferMode.ModeNumber = (UINT8) (SupportedModes->UdmaMode.Mode);
2188 } else if (SupportedModes->MultiWordDmaMode.Valid) {
2189 TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;
2190 TransferMode.ModeNumber = (UINT8) SupportedModes->MultiWordDmaMode.Mode;
2191 }
2192
2193 Status = AhciDeviceSetFeature (PciIo, AhciRegisters, Port, 0, 0x03, (UINT32)(*(UINT8 *)&TransferMode));
2194
2195 if (EFI_ERROR (Status)) {
2196 DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));
2197 continue;
2198 }
2199 //
2200 // Found a ATA or ATAPI device, add it into the device list.
2201 //
2202 CreateNewDeviceInfo (Instance, Port, 0, DeviceType, &Buffer);
2203 }
2204 }
2205 }
2206 return EFI_SUCCESS;
2207 }
2208