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