]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Ata/AhciPei/AhciMode.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AhciPei / AhciMode.c
1 /** @file
2 The AhciPei driver is used to manage ATA hard disk device working under AHCI
3 mode at PEI phase.
4
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "AhciPei.h"
12
13 #define ATA_CMD_TRUST_NON_DATA 0x5B
14 #define ATA_CMD_TRUST_RECEIVE 0x5C
15 #define ATA_CMD_TRUST_SEND 0x5E
16
17 //
18 // Look up table (IsWrite) for EFI_ATA_PASS_THRU_CMD_PROTOCOL
19 //
20 EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[2] = {
21 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
22 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
23 };
24
25 //
26 // Look up table (Lba48Bit, IsIsWrite) for ATA_CMD
27 //
28 UINT8 mAtaCommands[2][2] = {
29 {
30 ATA_CMD_READ_SECTORS, // 28-bit LBA; PIO read
31 ATA_CMD_WRITE_SECTORS // 28-bit LBA; PIO write
32 },
33 {
34 ATA_CMD_READ_SECTORS_EXT, // 48-bit LBA; PIO read
35 ATA_CMD_WRITE_SECTORS_EXT // 48-bit LBA; PIO write
36 }
37 };
38
39 //
40 // Look up table (IsTrustSend) for ATA_CMD
41 //
42 UINT8 mAtaTrustCommands[2] = {
43 ATA_CMD_TRUST_RECEIVE, // PIO read
44 ATA_CMD_TRUST_SEND // PIO write
45 };
46
47 //
48 // Look up table (Lba48Bit) for maximum transfer block number
49 //
50 #define MAX_28BIT_TRANSFER_BLOCK_NUM 0x100
51 //
52 // Due to limited resource for VTd PEI DMA buffer on platforms, the driver
53 // limits the maximum transfer block number for 48-bit addressing.
54 // Here, setting to 0x800 means that for device with 512-byte block size, the
55 // maximum buffer for DMA mapping will be 1M bytes in size.
56 //
57 #define MAX_48BIT_TRANSFER_BLOCK_NUM 0x800
58
59 UINT32 mMaxTransferBlockNumber[2] = {
60 MAX_28BIT_TRANSFER_BLOCK_NUM,
61 MAX_48BIT_TRANSFER_BLOCK_NUM
62 };
63
64 //
65 // The maximum total sectors count in 28 bit addressing mode
66 //
67 #define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff
68
69 /**
70 Read AHCI Operation register.
71
72 @param[in] AhciBar AHCI bar address.
73 @param[in] Offset The operation register offset.
74
75 @return The register content read.
76
77 **/
78 UINT32
79 AhciReadReg (
80 IN UINTN AhciBar,
81 IN UINT32 Offset
82 )
83 {
84 UINT32 Data;
85
86 Data = 0;
87 Data = MmioRead32 (AhciBar + Offset);
88
89 return Data;
90 }
91
92 /**
93 Write AHCI Operation register.
94
95 @param[in] AhciBar AHCI bar address.
96 @param[in] Offset The operation register offset.
97 @param[in] Data The Data used to write down.
98
99 **/
100 VOID
101 AhciWriteReg (
102 IN UINTN AhciBar,
103 IN UINT32 Offset,
104 IN UINT32 Data
105 )
106 {
107 MmioWrite32 (AhciBar + Offset, Data);
108 }
109
110 /**
111 Do AND operation with the value of AHCI Operation register.
112
113 @param[in] AhciBar AHCI bar address.
114 @param[in] Offset The operation register offset.
115 @param[in] AndData The data used to do AND operation.
116
117 **/
118 VOID
119 AhciAndReg (
120 IN UINTN AhciBar,
121 IN UINT32 Offset,
122 IN UINT32 AndData
123 )
124 {
125 UINT32 Data;
126
127 Data = AhciReadReg (AhciBar, Offset);
128 Data &= AndData;
129
130 AhciWriteReg (AhciBar, Offset, Data);
131 }
132
133 /**
134 Do OR operation with the Value of AHCI Operation register.
135
136 @param[in] AhciBar AHCI bar address.
137 @param[in] Offset The operation register offset.
138 @param[in] OrData The Data used to do OR operation.
139
140 **/
141 VOID
142 AhciOrReg (
143 IN UINTN AhciBar,
144 IN UINT32 Offset,
145 IN UINT32 OrData
146 )
147 {
148 UINT32 Data;
149
150 Data = AhciReadReg (AhciBar, Offset);
151 Data |= OrData;
152
153 AhciWriteReg (AhciBar, Offset, Data);
154 }
155
156 /**
157 Wait for memory set to the test Value.
158
159 @param[in] AhciBar AHCI bar address.
160 @param[in] Offset The memory offset to test.
161 @param[in] MaskValue The mask Value of memory.
162 @param[in] TestValue The test Value of memory.
163 @param[in] Timeout The timeout, in 100ns units, for wait memory set.
164
165 @retval EFI_DEVICE_ERROR The memory is not set.
166 @retval EFI_TIMEOUT The memory setting is time out.
167 @retval EFI_SUCCESS The memory is correct set.
168
169 **/
170 EFI_STATUS
171 EFIAPI
172 AhciWaitMmioSet (
173 IN UINTN AhciBar,
174 IN UINT32 Offset,
175 IN UINT32 MaskValue,
176 IN UINT32 TestValue,
177 IN UINT64 Timeout
178 )
179 {
180 UINT32 Value;
181 UINT32 Delay;
182
183 Delay = (UINT32)(DivU64x32 (Timeout, 1000) + 1);
184
185 do {
186 Value = AhciReadReg (AhciBar, Offset) & MaskValue;
187
188 if (Value == TestValue) {
189 return EFI_SUCCESS;
190 }
191
192 //
193 // Stall for 100 microseconds.
194 //
195 MicroSecondDelay (100);
196
197 Delay--;
198 } while (Delay > 0);
199
200 return EFI_TIMEOUT;
201 }
202
203 /**
204 Check the memory status to the test value.
205
206 @param[in] Address The memory address to test.
207 @param[in] MaskValue The mask value of memory.
208 @param[in] TestValue The test value of memory.
209
210 @retval EFI_NOT_READY The memory is not set.
211 @retval EFI_SUCCESS The memory is correct set.
212
213 **/
214 EFI_STATUS
215 AhciCheckMemSet (
216 IN UINTN Address,
217 IN UINT32 MaskValue,
218 IN UINT32 TestValue
219 )
220 {
221 UINT32 Value;
222
223 Value = *(volatile UINT32 *)Address;
224 Value &= MaskValue;
225
226 if (Value == TestValue) {
227 return EFI_SUCCESS;
228 } else {
229 return EFI_NOT_READY;
230 }
231 }
232
233 /**
234 Wait for the value of the specified system memory set to the test value.
235
236 @param[in] Address The system memory address to test.
237 @param[in] MaskValue The mask value of memory.
238 @param[in] TestValue The test value of memory.
239 @param[in] Timeout The timeout, in 100ns units, for wait memory set.
240
241 @retval EFI_TIMEOUT The system memory setting is time out.
242 @retval EFI_SUCCESS The system memory is correct set.
243
244 **/
245 EFI_STATUS
246 AhciWaitMemSet (
247 IN EFI_PHYSICAL_ADDRESS Address,
248 IN UINT32 MaskValue,
249 IN UINT32 TestValue,
250 IN UINT64 Timeout
251 )
252 {
253 UINT32 Value;
254 UINT64 Delay;
255 BOOLEAN InfiniteWait;
256
257 if (Timeout == 0) {
258 InfiniteWait = TRUE;
259 } else {
260 InfiniteWait = FALSE;
261 }
262
263 Delay = DivU64x32 (Timeout, 1000) + 1;
264
265 do {
266 //
267 // Access system memory to see if the value is the tested one.
268 //
269 // The system memory pointed by Address will be updated by the
270 // SATA Host Controller, "volatile" is introduced to prevent
271 // compiler from optimizing the access to the memory address
272 // to only read once.
273 //
274 Value = *(volatile UINT32 *)(UINTN)Address;
275 Value &= MaskValue;
276
277 if (Value == TestValue) {
278 return EFI_SUCCESS;
279 }
280
281 //
282 // Stall for 100 microseconds.
283 //
284 MicroSecondDelay (100);
285
286 Delay--;
287 } while (InfiniteWait || (Delay > 0));
288
289 return EFI_TIMEOUT;
290 }
291
292 /**
293
294 Clear the port interrupt and error status. It will also clear HBA interrupt
295 status.
296
297 @param[in] AhciBar AHCI bar address.
298 @param[in] Port The number of port.
299
300 **/
301 VOID
302 AhciClearPortStatus (
303 IN UINTN AhciBar,
304 IN UINT8 Port
305 )
306 {
307 UINT32 Offset;
308
309 //
310 // Clear any error status
311 //
312 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
313 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
314
315 //
316 // Clear any port interrupt status
317 //
318 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IS;
319 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
320
321 //
322 // Clear any HBA interrupt status
323 //
324 AhciWriteReg (AhciBar, AHCI_IS_OFFSET, AhciReadReg (AhciBar, AHCI_IS_OFFSET));
325 }
326
327 /**
328 Enable the FIS running for giving port.
329
330 @param[in] AhciBar AHCI bar address.
331 @param[in] Port The number of port.
332 @param[in] Timeout The timeout, in 100ns units, to enabling FIS.
333
334 @retval EFI_DEVICE_ERROR The FIS enable setting fails.
335 @retval EFI_TIMEOUT The FIS enable setting is time out.
336 @retval EFI_SUCCESS The FIS enable successfully.
337
338 **/
339 EFI_STATUS
340 AhciEnableFisReceive (
341 IN UINTN AhciBar,
342 IN UINT8 Port,
343 IN UINT64 Timeout
344 )
345 {
346 UINT32 Offset;
347
348 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
349 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
350
351 return EFI_SUCCESS;
352 }
353
354 /**
355 Disable the FIS running for giving port.
356
357 @param[in] AhciBar AHCI bar address.
358 @param[in] Port The number of port.
359 @param[in] Timeout The timeout value of disabling FIS, uses 100ns as a unit.
360
361 @retval EFI_DEVICE_ERROR The FIS disable setting fails.
362 @retval EFI_TIMEOUT The FIS disable setting is time out.
363 @retval EFI_UNSUPPORTED The port is in running state.
364 @retval EFI_SUCCESS The FIS disable successfully.
365
366 **/
367 EFI_STATUS
368 AhciDisableFisReceive (
369 IN UINTN AhciBar,
370 IN UINT8 Port,
371 IN UINT64 Timeout
372 )
373 {
374 UINT32 Offset;
375 UINT32 Data;
376
377 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
378 Data = AhciReadReg (AhciBar, Offset);
379
380 //
381 // Before disabling Fis receive, the DMA engine of the port should NOT be in
382 // running status.
383 //
384 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) != 0) {
385 return EFI_UNSUPPORTED;
386 }
387
388 //
389 // Check if the Fis receive DMA engine for the port is running.
390 //
391 if ((Data & AHCI_PORT_CMD_FR) != AHCI_PORT_CMD_FR) {
392 return EFI_SUCCESS;
393 }
394
395 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_FRE));
396
397 return AhciWaitMmioSet (
398 AhciBar,
399 Offset,
400 AHCI_PORT_CMD_FR,
401 0,
402 Timeout
403 );
404 }
405
406 /**
407 Build the command list, command table and prepare the fis receiver.
408
409 @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
410 @param[in] Port The number of port.
411 @param[in] PortMultiplier The number of port multiplier.
412 @param[in] FisIndex The offset index of the FIS base address.
413 @param[in] CommandFis The control fis will be used for the transfer.
414 @param[in] CommandList The command list will be used for the transfer.
415 @param[in] CommandSlotNumber The command slot will be used for the transfer.
416 @param[in,out] DataPhysicalAddr The pointer to the data buffer pci bus master
417 address.
418 @param[in] DataLength The data count to be transferred.
419
420 **/
421 VOID
422 AhciBuildCommand (
423 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,
424 IN UINT8 Port,
425 IN UINT8 PortMultiplier,
426 IN UINT8 FisIndex,
427 IN EFI_AHCI_COMMAND_FIS *CommandFis,
428 IN EFI_AHCI_COMMAND_LIST *CommandList,
429 IN UINT8 CommandSlotNumber,
430 IN OUT VOID *DataPhysicalAddr,
431 IN UINT32 DataLength
432 )
433 {
434 EFI_AHCI_REGISTERS *AhciRegisters;
435 UINTN AhciBar;
436 UINT64 BaseAddr;
437 UINT32 PrdtNumber;
438 UINT32 PrdtIndex;
439 UINTN RemainedData;
440 UINTN MemAddr;
441 DATA_64 Data64;
442 UINT32 Offset;
443
444 AhciRegisters = &Private->AhciRegisters;
445 AhciBar = Private->MmioBase;
446
447 //
448 // Filling the PRDT
449 //
450 PrdtNumber = (UINT32)DivU64x32 (
451 (UINT64)DataLength + AHCI_MAX_DATA_PER_PRDT - 1,
452 AHCI_MAX_DATA_PER_PRDT
453 );
454
455 //
456 // According to AHCI 1.3 spec, a PRDT entry can point to a maximum 4MB data block.
457 // It also limits that the maximum amount of the PRDT entry in the command table
458 // is 65535.
459 // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
460 // PRDT entries.
461 //
462 ASSERT (PrdtNumber <= AHCI_MAX_PRDT_NUMBER);
463 if (PrdtNumber > AHCI_MAX_PRDT_NUMBER) {
464 return;
465 }
466
467 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
468
469 BaseAddr = Data64.Uint64;
470
471 ZeroMem ((VOID *)((UINTN)BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
472
473 ZeroMem (AhciRegisters->AhciCmdTable, sizeof (EFI_AHCI_COMMAND_TABLE));
474
475 CommandFis->AhciCFisPmNum = PortMultiplier;
476
477 CopyMem (&AhciRegisters->AhciCmdTable->CommandFis, CommandFis, sizeof (EFI_AHCI_COMMAND_FIS));
478
479 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
480 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_DLAE | AHCI_PORT_CMD_ATAPI));
481
482 RemainedData = (UINTN)DataLength;
483 MemAddr = (UINTN)DataPhysicalAddr;
484 CommandList->AhciCmdPrdtl = PrdtNumber;
485
486 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
487 if (RemainedData < AHCI_MAX_DATA_PER_PRDT) {
488 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
489 } else {
490 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = AHCI_MAX_DATA_PER_PRDT - 1;
491 }
492
493 Data64.Uint64 = (UINT64)MemAddr;
494 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
495 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
496 RemainedData -= AHCI_MAX_DATA_PER_PRDT;
497 MemAddr += AHCI_MAX_DATA_PER_PRDT;
498 }
499
500 //
501 // Set the last PRDT to Interrupt On Complete
502 //
503 if (PrdtNumber > 0) {
504 AhciRegisters->AhciCmdTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
505 }
506
507 CopyMem (
508 (VOID *)((UINTN)AhciRegisters->AhciCmdList + (UINTN)CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
509 CommandList,
510 sizeof (EFI_AHCI_COMMAND_LIST)
511 );
512
513 Data64.Uint64 = (UINT64)(UINTN)AhciRegisters->AhciCmdTable;
514 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
515 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
516 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;
517 }
518
519 /**
520 Build a command FIS.
521
522 @param[in,out] CmdFis A pointer to the EFI_AHCI_COMMAND_FIS data
523 structure.
524 @param[in] AtaCommandBlock A pointer to the EFI_ATA_COMMAND_BLOCK data
525 structure.
526
527 **/
528 VOID
529 AhciBuildCommandFis (
530 IN OUT EFI_AHCI_COMMAND_FIS *CmdFis,
531 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock
532 )
533 {
534 ZeroMem (CmdFis, sizeof (EFI_AHCI_COMMAND_FIS));
535
536 CmdFis->AhciCFisType = AHCI_FIS_REGISTER_H2D;
537 //
538 // Indicator it's a command
539 //
540 CmdFis->AhciCFisCmdInd = 0x1;
541 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
542
543 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
544 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
545
546 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
547 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
548
549 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
550 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
551
552 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
553 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
554
555 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
556 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
557
558 CmdFis->AhciCFisDevHead = (UINT8)(AtaCommandBlock->AtaDeviceHead | 0xE0);
559 }
560
561 /**
562 Stop command running for giving port
563
564 @param[in] AhciBar AHCI bar address.
565 @param[in] Port The number of port.
566 @param[in] Timeout The timeout value, in 100ns units, to stop.
567
568 @retval EFI_DEVICE_ERROR The command stop unsuccessfully.
569 @retval EFI_TIMEOUT The operation is time out.
570 @retval EFI_SUCCESS The command stop successfully.
571
572 **/
573 EFI_STATUS
574 AhciStopCommand (
575 IN UINTN AhciBar,
576 IN UINT8 Port,
577 IN UINT64 Timeout
578 )
579 {
580 UINT32 Offset;
581 UINT32 Data;
582
583 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
584 Data = AhciReadReg (AhciBar, Offset);
585
586 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) == 0) {
587 return EFI_SUCCESS;
588 }
589
590 if ((Data & AHCI_PORT_CMD_ST) != 0) {
591 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_ST));
592 }
593
594 return AhciWaitMmioSet (
595 AhciBar,
596 Offset,
597 AHCI_PORT_CMD_CR,
598 0,
599 Timeout
600 );
601 }
602
603 /**
604 Start command for give slot on specific port.
605
606 @param[in] AhciBar AHCI bar address.
607 @param[in] Port The number of port.
608 @param[in] CommandSlot The number of Command Slot.
609 @param[in] Timeout The timeout value, in 100ns units, to start.
610
611 @retval EFI_DEVICE_ERROR The command start unsuccessfully.
612 @retval EFI_TIMEOUT The operation is time out.
613 @retval EFI_SUCCESS The command start successfully.
614
615 **/
616 EFI_STATUS
617 AhciStartCommand (
618 IN UINTN AhciBar,
619 IN UINT8 Port,
620 IN UINT8 CommandSlot,
621 IN UINT64 Timeout
622 )
623 {
624 UINT32 CmdSlotBit;
625 EFI_STATUS Status;
626 UINT32 PortStatus;
627 UINT32 StartCmd;
628 UINT32 PortTfd;
629 UINT32 Offset;
630 UINT32 Capability;
631
632 //
633 // Collect AHCI controller information
634 //
635 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
636
637 CmdSlotBit = (UINT32)(1 << CommandSlot);
638
639 AhciClearPortStatus (
640 AhciBar,
641 Port
642 );
643
644 Status = AhciEnableFisReceive (
645 AhciBar,
646 Port,
647 Timeout
648 );
649 if (EFI_ERROR (Status)) {
650 return Status;
651 }
652
653 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
654 PortStatus = AhciReadReg (AhciBar, Offset);
655
656 StartCmd = 0;
657 if ((PortStatus & AHCI_PORT_CMD_ALPE) != 0) {
658 StartCmd = AhciReadReg (AhciBar, Offset);
659 StartCmd &= ~AHCI_PORT_CMD_ICC_MASK;
660 StartCmd |= AHCI_PORT_CMD_ACTIVE;
661 }
662
663 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
664 PortTfd = AhciReadReg (AhciBar, Offset);
665
666 if ((PortTfd & (AHCI_PORT_TFD_BSY | AHCI_PORT_TFD_DRQ)) != 0) {
667 if ((Capability & BIT24) != 0) {
668 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
669 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_CLO);
670
671 AhciWaitMmioSet (
672 AhciBar,
673 Offset,
674 AHCI_PORT_CMD_CLO,
675 0,
676 Timeout
677 );
678 }
679 }
680
681 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
682 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_ST | StartCmd);
683
684 //
685 // Setting the command
686 //
687 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CI;
688 AhciAndReg (AhciBar, Offset, 0);
689 AhciOrReg (AhciBar, Offset, CmdSlotBit);
690
691 return EFI_SUCCESS;
692 }
693
694 /**
695 Start a PIO Data transfer on specific port.
696
697 @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
698 @param[in] Port The number of port.
699 @param[in] PortMultiplier The number of port multiplier.
700 @param[in] FisIndex The offset index of the FIS base address.
701 @param[in] Read The transfer direction.
702 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
703 @param[in,out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
704 @param[in,out] MemoryAddr The pointer to the data buffer.
705 @param[in] DataCount The data count to be transferred.
706 @param[in] Timeout The timeout value of PIO data transfer, uses
707 100ns as a unit.
708
709 @retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
710 @retval EFI_TIMEOUT The operation is time out.
711 @retval EFI_UNSUPPORTED The device is not ready for transfer.
712 @retval EFI_OUT_OF_RESOURCES The operation fails due to lack of resources.
713 @retval EFI_SUCCESS The PIO data transfer executes successfully.
714
715 **/
716 EFI_STATUS
717 AhciPioTransfer (
718 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,
719 IN UINT8 Port,
720 IN UINT8 PortMultiplier,
721 IN UINT8 FisIndex,
722 IN BOOLEAN Read,
723 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
724 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
725 IN OUT VOID *MemoryAddr,
726 IN UINT32 DataCount,
727 IN UINT64 Timeout
728 )
729 {
730 EFI_STATUS Status;
731 EDKII_IOMMU_OPERATION MapOp;
732 UINTN MapLength;
733 EFI_PHYSICAL_ADDRESS PhyAddr;
734 VOID *MapData;
735 EFI_AHCI_REGISTERS *AhciRegisters;
736 UINTN AhciBar;
737 BOOLEAN InfiniteWait;
738 UINT32 Offset;
739 UINT32 OldRfisLo;
740 UINT32 OldRfisHi;
741 UINT32 OldCmdListLo;
742 UINT32 OldCmdListHi;
743 DATA_64 Data64;
744 UINT32 FisBaseAddr;
745 UINT32 Delay;
746 EFI_AHCI_COMMAND_FIS CFis;
747 EFI_AHCI_COMMAND_LIST CmdList;
748 UINT32 PortTfd;
749 UINT32 PrdCount;
750 BOOLEAN PioFisReceived;
751 BOOLEAN D2hFisReceived;
752
753 //
754 // Current driver implementation supports up to a maximum of AHCI_MAX_PRDT_NUMBER
755 // PRDT entries.
756 //
757 if (DataCount / (UINT32)AHCI_MAX_PRDT_NUMBER > AHCI_MAX_DATA_PER_PRDT) {
758 DEBUG ((
759 DEBUG_ERROR,
760 "%a: Driver only support a maximum of 0x%x PRDT entries, "
761 "current number of data byte 0x%x is too large, maximum allowed is 0x%x.\n",
762 __FUNCTION__,
763 AHCI_MAX_PRDT_NUMBER,
764 DataCount,
765 AHCI_MAX_PRDT_NUMBER * AHCI_MAX_DATA_PER_PRDT
766 ));
767 return EFI_UNSUPPORTED;
768 }
769
770 MapOp = Read ? EdkiiIoMmuOperationBusMasterWrite :
771 EdkiiIoMmuOperationBusMasterRead;
772 MapLength = DataCount;
773 Status = IoMmuMap (
774 MapOp,
775 MemoryAddr,
776 &MapLength,
777 &PhyAddr,
778 &MapData
779 );
780 if (EFI_ERROR (Status) || (MapLength != DataCount)) {
781 DEBUG ((DEBUG_ERROR, "%a: Fail to map data buffer.\n", __FUNCTION__));
782 return EFI_OUT_OF_RESOURCES;
783 }
784
785 AhciRegisters = &Private->AhciRegisters;
786 AhciBar = Private->MmioBase;
787 InfiniteWait = (Timeout == 0) ? TRUE : FALSE;
788
789 //
790 // Fill FIS base address register
791 //
792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
793 OldRfisLo = AhciReadReg (AhciBar, Offset);
794 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
795 OldRfisHi = AhciReadReg (AhciBar, Offset);
796 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
797 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
798 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
800 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
801
802 //
803 // Single task environment, we only use one command table for all port
804 //
805 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
806 OldCmdListLo = AhciReadReg (AhciBar, Offset);
807 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
808 OldCmdListHi = AhciReadReg (AhciBar, Offset);
809 Data64.Uint64 = (UINTN)(AhciRegisters->AhciCmdList);
810 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
811 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
812 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
813 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
814
815 //
816 // Package read needed
817 //
818 AhciBuildCommandFis (&CFis, AtaCommandBlock);
819
820 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
821
822 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
823 CmdList.AhciCmdW = Read ? 0 : 1;
824
825 AhciBuildCommand (
826 Private,
827 Port,
828 PortMultiplier,
829 FisIndex,
830 &CFis,
831 &CmdList,
832 0,
833 (VOID *)(UINTN)PhyAddr,
834 DataCount
835 );
836
837 Status = AhciStartCommand (
838 AhciBar,
839 Port,
840 0,
841 Timeout
842 );
843 if (EFI_ERROR (Status)) {
844 goto Exit;
845 }
846
847 //
848 // Checking the status and wait the driver sending Data
849 //
850 FisBaseAddr = (UINT32)(UINTN)AhciRegisters->AhciRFis + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
851 if (Read) {
852 //
853 // Wait device sends the PIO setup fis before data transfer
854 //
855 Status = EFI_TIMEOUT;
856 Delay = (UINT32)DivU64x32 (Timeout, 1000) + 1;
857 do {
858 PioFisReceived = FALSE;
859 D2hFisReceived = FALSE;
860 Offset = FisBaseAddr + AHCI_PIO_FIS_OFFSET;
861 Status = AhciCheckMemSet (Offset, AHCI_FIS_TYPE_MASK, AHCI_FIS_PIO_SETUP);
862 if (!EFI_ERROR (Status)) {
863 DEBUG ((DEBUG_INFO, "%a: PioFisReceived.\n", __FUNCTION__));
864 PioFisReceived = TRUE;
865 }
866
867 //
868 // According to SATA 2.6 spec section 11.7, D2h FIS means an error encountered.
869 // But Qemu and Marvel 9230 sata controller may just receive a D2h FIS from
870 // device after the transaction is finished successfully.
871 // To get better device compatibilities, we further check if the PxTFD's
872 // ERR bit is set. By this way, we can know if there is a real error happened.
873 //
874 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
875 Status = AhciCheckMemSet (Offset, AHCI_FIS_TYPE_MASK, AHCI_FIS_REGISTER_D2H);
876 if (!EFI_ERROR (Status)) {
877 DEBUG ((DEBUG_INFO, "%a: D2hFisReceived.\n", __FUNCTION__));
878 D2hFisReceived = TRUE;
879 }
880
881 if (PioFisReceived || D2hFisReceived) {
882 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
883 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
884 //
885 // PxTFD will be updated if there is a D2H or SetupFIS received.
886 //
887 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
888 Status = EFI_DEVICE_ERROR;
889 break;
890 }
891
892 PrdCount = *(volatile UINT32 *)(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
893 if (PrdCount == DataCount) {
894 Status = EFI_SUCCESS;
895 break;
896 }
897 }
898
899 //
900 // Stall for 100 microseconds.
901 //
902 MicroSecondDelay (100);
903
904 Delay--;
905 if (Delay == 0) {
906 Status = EFI_TIMEOUT;
907 }
908 } while (InfiniteWait || (Delay > 0));
909 } else {
910 //
911 // Wait for D2H Fis is received
912 //
913 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
914 Status = AhciWaitMemSet (
915 Offset,
916 AHCI_FIS_TYPE_MASK,
917 AHCI_FIS_REGISTER_D2H,
918 Timeout
919 );
920 if (EFI_ERROR (Status)) {
921 DEBUG ((DEBUG_ERROR, "%a: AhciWaitMemSet (%r)\n", __FUNCTION__, Status));
922 goto Exit;
923 }
924
925 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
926 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
927 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
928 Status = EFI_DEVICE_ERROR;
929 }
930 }
931
932 Exit:
933 AhciStopCommand (
934 AhciBar,
935 Port,
936 Timeout
937 );
938
939 AhciDisableFisReceive (
940 AhciBar,
941 Port,
942 Timeout
943 );
944
945 if (MapData != NULL) {
946 IoMmuUnmap (MapData);
947 }
948
949 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
950 AhciWriteReg (AhciBar, Offset, OldRfisLo);
951 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
952 AhciWriteReg (AhciBar, Offset, OldRfisHi);
953
954 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
955 AhciWriteReg (AhciBar, Offset, OldCmdListLo);
956 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
957 AhciWriteReg (AhciBar, Offset, OldCmdListHi);
958
959 return Status;
960 }
961
962 /**
963 Start a non data transfer on specific port.
964
965 @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
966 @param[in] Port The number of port.
967 @param[in] PortMultiplier The number of port multiplier.
968 @param[in] FisIndex The offset index of the FIS base address.
969 @param[in] AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
970 @param[in,out] AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
971 @param[in] Timeout The timeout value of non data transfer, uses
972 100ns as a unit.
973
974 @retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
975 @retval EFI_TIMEOUT The operation is time out.
976 @retval EFI_UNSUPPORTED The device is not ready for transfer.
977 @retval EFI_SUCCESS The non data transfer executes successfully.
978
979 **/
980 EFI_STATUS
981 AhciNonDataTransfer (
982 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,
983 IN UINT8 Port,
984 IN UINT8 PortMultiplier,
985 IN UINT8 FisIndex,
986 IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
987 IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
988 IN UINT64 Timeout
989 )
990 {
991 EFI_STATUS Status;
992 UINTN AhciBar;
993 EFI_AHCI_REGISTERS *AhciRegisters;
994 UINTN FisBaseAddr;
995 UINTN Offset;
996 UINT32 PortTfd;
997 EFI_AHCI_COMMAND_FIS CFis;
998 EFI_AHCI_COMMAND_LIST CmdList;
999
1000 AhciBar = Private->MmioBase;
1001 AhciRegisters = &Private->AhciRegisters;
1002
1003 //
1004 // Package read needed
1005 //
1006 AhciBuildCommandFis (&CFis, AtaCommandBlock);
1007
1008 ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));
1009
1010 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1011
1012 AhciBuildCommand (
1013 Private,
1014 Port,
1015 PortMultiplier,
1016 FisIndex,
1017 &CFis,
1018 &CmdList,
1019 0,
1020 NULL,
1021 0
1022 );
1023
1024 Status = AhciStartCommand (
1025 AhciBar,
1026 Port,
1027 0,
1028 Timeout
1029 );
1030 if (EFI_ERROR (Status)) {
1031 goto Exit;
1032 }
1033
1034 //
1035 // Wait device sends the Response Fis
1036 //
1037 FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + sizeof (EFI_AHCI_RECEIVED_FIS) * FisIndex;
1038 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
1039 Status = AhciWaitMemSet (
1040 Offset,
1041 AHCI_FIS_TYPE_MASK,
1042 AHCI_FIS_REGISTER_D2H,
1043 Timeout
1044 );
1045
1046 if (EFI_ERROR (Status)) {
1047 goto Exit;
1048 }
1049
1050 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1051 PortTfd = AhciReadReg (AhciBar, (UINT32)Offset);
1052 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
1053 Status = EFI_DEVICE_ERROR;
1054 }
1055
1056 Exit:
1057 AhciStopCommand (
1058 AhciBar,
1059 Port,
1060 Timeout
1061 );
1062
1063 AhciDisableFisReceive (
1064 AhciBar,
1065 Port,
1066 Timeout
1067 );
1068
1069 return Status;
1070 }
1071
1072 /**
1073 Do AHCI HBA reset.
1074
1075 @param[in] AhciBar AHCI bar address.
1076 @param[in] Timeout The timeout, in 100ns units, to reset.
1077
1078 @retval EFI_DEVICE_ERROR AHCI controller is failed to complete hardware reset.
1079 @retval EFI_TIMEOUT The reset operation is time out.
1080 @retval EFI_SUCCESS AHCI controller is reset successfully.
1081
1082 **/
1083 EFI_STATUS
1084 AhciReset (
1085 IN UINTN AhciBar,
1086 IN UINT64 Timeout
1087 )
1088 {
1089 UINT32 Delay;
1090 UINT32 Value;
1091 UINT32 Capability;
1092
1093 //
1094 // Collect AHCI controller information
1095 //
1096 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1097
1098 //
1099 // Enable AE before accessing any AHCI registers if Supports AHCI Mode Only is not set
1100 //
1101 if ((Capability & AHCI_CAP_SAM) == 0) {
1102 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1103 }
1104
1105 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_RESET);
1106
1107 Delay = (UINT32)(DivU64x32 (Timeout, 1000) + 1);
1108
1109 do {
1110 Value = AhciReadReg (AhciBar, AHCI_GHC_OFFSET);
1111 if ((Value & AHCI_GHC_RESET) == 0) {
1112 return EFI_SUCCESS;
1113 }
1114
1115 //
1116 // Stall for 100 microseconds.
1117 //
1118 MicroSecondDelay (100);
1119
1120 Delay--;
1121 } while (Delay > 0);
1122
1123 return EFI_TIMEOUT;
1124 }
1125
1126 /**
1127 Send Identify Drive command to a specific device.
1128
1129 @param[in] Private The pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA.
1130 @param[in] Port The number of port.
1131 @param[in] PortMultiplier The port multiplier port number.
1132 @param[in] FisIndex The offset index of the FIS base address.
1133 @param[in] Buffer The data buffer to store IDENTIFY PACKET data.
1134
1135 @retval EFI_SUCCESS The cmd executes successfully.
1136 @retval EFI_INVALID_PARAMETER Buffer is NULL.
1137 @retval EFI_DEVICE_ERROR The cmd abort with error occurs.
1138 @retval EFI_TIMEOUT The operation is time out.
1139 @retval EFI_UNSUPPORTED The device is not ready for executing.
1140
1141 **/
1142 EFI_STATUS
1143 AhciIdentify (
1144 IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,
1145 IN UINT8 Port,
1146 IN UINT8 PortMultiplier,
1147 IN UINT8 FisIndex,
1148 IN ATA_IDENTIFY_DATA *Buffer
1149 )
1150 {
1151 EFI_STATUS Status;
1152 EFI_ATA_COMMAND_BLOCK Acb;
1153 EFI_ATA_STATUS_BLOCK Asb;
1154
1155 if (Buffer == NULL) {
1156 return EFI_INVALID_PARAMETER;
1157 }
1158
1159 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
1160 ZeroMem (&Asb, sizeof (EFI_ATA_STATUS_BLOCK));
1161
1162 Acb.AtaCommand = ATA_CMD_IDENTIFY_DRIVE;
1163 Acb.AtaSectorCount = 1;
1164
1165 Status = AhciPioTransfer (
1166 Private,
1167 Port,
1168 PortMultiplier,
1169 FisIndex,
1170 TRUE,
1171 &Acb,
1172 &Asb,
1173 Buffer,
1174 sizeof (ATA_IDENTIFY_DATA),
1175 ATA_TIMEOUT
1176 );
1177
1178 return Status;
1179 }
1180
1181 /**
1182 Collect the number of bits set within a port bitmap.
1183
1184 @param[in] PortBitMap A 32-bit wide bit map of ATA AHCI ports.
1185
1186 @retval The number of bits set in the bitmap.
1187
1188 **/
1189 UINT8
1190 AhciGetNumberOfPortsFromMap (
1191 IN UINT32 PortBitMap
1192 )
1193 {
1194 UINT8 NumberOfPorts;
1195
1196 NumberOfPorts = 0;
1197
1198 while (PortBitMap != 0) {
1199 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1200 NumberOfPorts++;
1201 }
1202
1203 PortBitMap = PortBitMap >> 1;
1204 }
1205
1206 return NumberOfPorts;
1207 }
1208
1209 /**
1210 Get the specified port number from a port bitmap.
1211
1212 @param[in] PortBitMap A 32-bit wide bit map of ATA AHCI ports.
1213 @param[in] PortIndex The specified port index.
1214 @param[out] Port The port number of the port specified by PortIndex.
1215
1216 @retval EFI_SUCCESS The specified port is found and its port number is
1217 in Port.
1218 @retval EFI_NOT_FOUND Cannot find the specified port within the port bitmap.
1219
1220 **/
1221 EFI_STATUS
1222 AhciGetPortFromMap (
1223 IN UINT32 PortBitMap,
1224 IN UINT8 PortIndex,
1225 OUT UINT8 *Port
1226 )
1227 {
1228 if (PortIndex == 0) {
1229 return EFI_NOT_FOUND;
1230 }
1231
1232 *Port = 0;
1233
1234 while (PortBitMap != 0) {
1235 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1236 PortIndex--;
1237
1238 //
1239 // Found the port specified by PortIndex.
1240 //
1241 if (PortIndex == 0) {
1242 return EFI_SUCCESS;
1243 }
1244 }
1245
1246 PortBitMap = PortBitMap >> 1;
1247 *Port = *Port + 1;
1248 }
1249
1250 return EFI_NOT_FOUND;
1251 }
1252
1253 /**
1254 Allocate transfer-related data struct which is used at AHCI mode.
1255
1256 @param[in,out] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA instance.
1257
1258 @retval EFI_SUCCESS Data structures are allocated successfully.
1259 @retval Others Data structures are not allocated successfully.
1260
1261 **/
1262 EFI_STATUS
1263 AhciCreateTransferDescriptor (
1264 IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private
1265 )
1266 {
1267 EFI_STATUS Status;
1268 UINTN AhciBar;
1269 EFI_AHCI_REGISTERS *AhciRegisters;
1270 EFI_PHYSICAL_ADDRESS DeviceAddress;
1271 VOID *Base;
1272 VOID *Mapping;
1273 UINT32 Capability;
1274 UINT32 PortImplementBitMap;
1275 UINT8 MaxPortNumber;
1276 UINT8 MaxCommandSlotNumber;
1277 UINTN MaxRFisSize;
1278 UINTN MaxCmdListSize;
1279 UINTN MaxCmdTableSize;
1280
1281 AhciBar = Private->MmioBase;
1282 AhciRegisters = &Private->AhciRegisters;
1283
1284 //
1285 // Collect AHCI controller information
1286 //
1287 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1288
1289 //
1290 // Get the number of command slots per port supported by this HBA.
1291 //
1292 MaxCommandSlotNumber = (UINT8)(((Capability & 0x1F00) >> 8) + 1);
1293 ASSERT (MaxCommandSlotNumber > 0);
1294 if (MaxCommandSlotNumber == 0) {
1295 return EFI_DEVICE_ERROR;
1296 }
1297
1298 //
1299 // Get the highest bit of implemented ports which decides how many bytes are
1300 // allocated for recived FIS.
1301 //
1302 PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1303 MaxPortNumber = (UINT8)(UINTN)(HighBitSet32 (PortImplementBitMap) + 1);
1304 if (MaxPortNumber == 0) {
1305 return EFI_DEVICE_ERROR;
1306 }
1307
1308 //
1309 // Get the number of ports that actually needed to be initialized.
1310 //
1311 MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1312
1313 //
1314 // Allocate memory for received FIS.
1315 //
1316 MaxRFisSize = MaxPortNumber * sizeof (EFI_AHCI_RECEIVED_FIS);
1317 Status = IoMmuAllocateBuffer (
1318 EFI_SIZE_TO_PAGES (MaxRFisSize),
1319 &Base,
1320 &DeviceAddress,
1321 &Mapping
1322 );
1323 if (EFI_ERROR (Status)) {
1324 return EFI_OUT_OF_RESOURCES;
1325 }
1326
1327 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1328 AhciRegisters->AhciRFis = Base;
1329 AhciRegisters->AhciRFisMap = Mapping;
1330 AhciRegisters->MaxRFisSize = MaxRFisSize;
1331 ZeroMem (AhciRegisters->AhciRFis, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxRFisSize));
1332
1333 //
1334 // Allocate memory for command list.
1335 // Note that the implemenation is a single task model which only use a command
1336 // list for each port.
1337 //
1338 MaxCmdListSize = 1 * sizeof (EFI_AHCI_COMMAND_LIST);
1339 Status = IoMmuAllocateBuffer (
1340 EFI_SIZE_TO_PAGES (MaxCmdListSize),
1341 &Base,
1342 &DeviceAddress,
1343 &Mapping
1344 );
1345 if (EFI_ERROR (Status)) {
1346 Status = EFI_OUT_OF_RESOURCES;
1347 goto ErrorExit;
1348 }
1349
1350 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1351 AhciRegisters->AhciCmdList = Base;
1352 AhciRegisters->AhciCmdListMap = Mapping;
1353 AhciRegisters->MaxCmdListSize = MaxCmdListSize;
1354 ZeroMem (AhciRegisters->AhciCmdList, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdListSize));
1355
1356 //
1357 // Allocate memory for command table
1358 // According to AHCI 1.3 spec, a PRD table can contain maximum 65535 entries.
1359 //
1360 MaxCmdTableSize = sizeof (EFI_AHCI_COMMAND_TABLE);
1361 Status = IoMmuAllocateBuffer (
1362 EFI_SIZE_TO_PAGES (MaxCmdTableSize),
1363 &Base,
1364 &DeviceAddress,
1365 &Mapping
1366 );
1367 if (EFI_ERROR (Status)) {
1368 Status = EFI_OUT_OF_RESOURCES;
1369 goto ErrorExit;
1370 }
1371
1372 ASSERT (DeviceAddress == ((EFI_PHYSICAL_ADDRESS)(UINTN)Base));
1373 AhciRegisters->AhciCmdTable = Base;
1374 AhciRegisters->AhciCmdTableMap = Mapping;
1375 AhciRegisters->MaxCmdTableSize = MaxCmdTableSize;
1376 ZeroMem (AhciRegisters->AhciCmdTable, EFI_PAGE_SIZE * EFI_SIZE_TO_PAGES (MaxCmdTableSize));
1377
1378 return EFI_SUCCESS;
1379
1380 ErrorExit:
1381 if (AhciRegisters->AhciRFisMap != NULL) {
1382 IoMmuFreeBuffer (
1383 EFI_SIZE_TO_PAGES (AhciRegisters->MaxRFisSize),
1384 AhciRegisters->AhciRFis,
1385 AhciRegisters->AhciRFisMap
1386 );
1387 AhciRegisters->AhciRFis = NULL;
1388 }
1389
1390 if (AhciRegisters->AhciCmdListMap != NULL) {
1391 IoMmuFreeBuffer (
1392 EFI_SIZE_TO_PAGES (AhciRegisters->MaxCmdListSize),
1393 AhciRegisters->AhciCmdList,
1394 AhciRegisters->AhciCmdListMap
1395 );
1396 AhciRegisters->AhciCmdList = NULL;
1397 }
1398
1399 return Status;
1400 }
1401
1402 /**
1403 Gets ATA device Capacity according to ATA 6.
1404
1405 This function returns the capacity of the ATA device if it follows
1406 ATA 6 to support 48 bit addressing.
1407
1408 @param[in] IdentifyData A pointer to ATA_IDENTIFY_DATA structure.
1409
1410 @return The capacity of the ATA device or 0 if the device does not support
1411 48-bit addressing defined in ATA 6.
1412
1413 **/
1414 EFI_LBA
1415 GetAtapi6Capacity (
1416 IN ATA_IDENTIFY_DATA *IdentifyData
1417 )
1418 {
1419 EFI_LBA Capacity;
1420 EFI_LBA TmpLba;
1421 UINTN Index;
1422
1423 if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
1424 //
1425 // The device doesn't support 48 bit addressing
1426 //
1427 return 0;
1428 }
1429
1430 //
1431 // 48 bit address feature set is supported, get maximum capacity
1432 //
1433 Capacity = 0;
1434 for (Index = 0; Index < 4; Index++) {
1435 //
1436 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
1437 //
1438 TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
1439 Capacity |= LShiftU64 (TmpLba, 16 * Index);
1440 }
1441
1442 return Capacity;
1443 }
1444
1445 /**
1446 Identifies ATA device via the Identify data.
1447
1448 This function identifies the ATA device and initializes the media information.
1449
1450 @attention This is boundary function that may receive untrusted input.
1451 @attention The input is from peripheral hardware device.
1452
1453 The Identify Drive command response data from an ATA device is the peripheral
1454 hardware input, so this routine will do basic validation for the Identify Drive
1455 command response data.
1456
1457 @param[in,out] DeviceData A pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
1458
1459 @retval EFI_SUCCESS The device is successfully identified and media
1460 information is correctly initialized.
1461 @retval EFI_UNSUPPORTED The device is not a valid ATA device (hard disk).
1462
1463 **/
1464 EFI_STATUS
1465 IdentifyAtaDevice (
1466 IN OUT PEI_AHCI_ATA_DEVICE_DATA *DeviceData
1467 )
1468 {
1469 ATA_IDENTIFY_DATA *IdentifyData;
1470 EFI_PEI_BLOCK_IO2_MEDIA *Media;
1471 EFI_LBA Capacity;
1472 UINT32 MaxSectorCount;
1473 UINT16 PhyLogicSectorSupport;
1474
1475 IdentifyData = DeviceData->IdentifyData;
1476 Media = &DeviceData->Media;
1477
1478 if ((IdentifyData->config & BIT15) != 0) {
1479 DEBUG ((
1480 DEBUG_ERROR,
1481 "%a: Not a hard disk device on Port 0x%x PortMultiplierPort 0x%x\n",
1482 __FUNCTION__,
1483 DeviceData->Port,
1484 DeviceData->PortMultiplier
1485 ));
1486 return EFI_UNSUPPORTED;
1487 }
1488
1489 DEBUG ((
1490 DEBUG_INFO,
1491 "%a: Identify Device: Port 0x%x PortMultiplierPort 0x%x\n",
1492 __FUNCTION__,
1493 DeviceData->Port,
1494 DeviceData->PortMultiplier
1495 ));
1496
1497 //
1498 // Skip checking whether the WORD 88 (supported UltraDMA by drive), since the
1499 // driver only support PIO data transfer for now.
1500 //
1501
1502 //
1503 // Get the capacity information of the device.
1504 //
1505 Capacity = GetAtapi6Capacity (IdentifyData);
1506 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
1507 //
1508 // Capacity exceeds 120GB. 48-bit addressing is really needed
1509 //
1510 DeviceData->Lba48Bit = TRUE;
1511 } else {
1512 //
1513 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
1514 //
1515 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) |
1516 IdentifyData->user_addressable_sectors_lo;
1517 DeviceData->Lba48Bit = FALSE;
1518 }
1519
1520 if (Capacity == 0) {
1521 DEBUG ((DEBUG_ERROR, "%a: Invalid Capacity (0) for ATA device.\n", __FUNCTION__));
1522 return EFI_UNSUPPORTED;
1523 }
1524
1525 Media->LastBlock = (EFI_PEI_LBA)(Capacity - 1);
1526
1527 Media->BlockSize = 0x200;
1528 //
1529 // Check whether Long Physical Sector Feature is supported
1530 //
1531 PhyLogicSectorSupport = IdentifyData->phy_logic_sector_support;
1532 DEBUG ((
1533 DEBUG_INFO,
1534 "%a: PhyLogicSectorSupport = 0x%x\n",
1535 __FUNCTION__,
1536 PhyLogicSectorSupport
1537 ));
1538 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
1539 //
1540 // Check logical block size
1541 //
1542 if ((PhyLogicSectorSupport & BIT12) != 0) {
1543 Media->BlockSize = (UINT32)(((IdentifyData->logic_sector_size_hi << 16) |
1544 IdentifyData->logic_sector_size_lo) * sizeof (UINT16));
1545 }
1546 }
1547
1548 //
1549 // Check BlockSize validity
1550 //
1551 MaxSectorCount = mMaxTransferBlockNumber[DeviceData->Lba48Bit];
1552 if ((Media->BlockSize == 0) || (Media->BlockSize > MAX_UINT32 / MaxSectorCount)) {
1553 DEBUG ((DEBUG_ERROR, "%a: Invalid BlockSize (0x%x).\n", __FUNCTION__, Media->BlockSize));
1554 return EFI_UNSUPPORTED;
1555 }
1556
1557 DEBUG ((
1558 DEBUG_INFO,
1559 "%a: BlockSize = 0x%x, LastBlock = 0x%lx\n",
1560 __FUNCTION__,
1561 Media->BlockSize,
1562 Media->LastBlock
1563 ));
1564
1565 if ((IdentifyData->trusted_computing_support & BIT0) != 0) {
1566 DEBUG ((DEBUG_INFO, "%a: Found Trust Computing feature support.\n", __FUNCTION__));
1567 DeviceData->TrustComputing = TRUE;
1568 }
1569
1570 Media->InterfaceType = MSG_SATA_DP;
1571 Media->RemovableMedia = FALSE;
1572 Media->MediaPresent = TRUE;
1573 Media->ReadOnly = FALSE;
1574
1575 return EFI_SUCCESS;
1576 }
1577
1578 /**
1579 Allocate device information data structure to contain device information.
1580 And insert the data structure to the tail of device list for tracing.
1581
1582 @param[in,out] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA
1583 instance.
1584 @param[in] DeviceIndex The device index.
1585 @param[in] Port The port number of the ATA device to send
1586 the command.
1587 @param[in] PortMultiplierPort The port multiplier port number of the ATA
1588 device to send the command.
1589 If there is no port multiplier, then specify
1590 0xFFFF.
1591 @param[in] FisIndex The index of the FIS of the ATA device to
1592 send the command.
1593 @param[in] IdentifyData The data buffer to store the output of the
1594 IDENTIFY command.
1595
1596 @retval EFI_SUCCESS Successfully insert the ATA device to the
1597 tail of device list.
1598 @retval EFI_OUT_OF_RESOURCES Not enough resource.
1599
1600 **/
1601 EFI_STATUS
1602 CreateNewDevice (
1603 IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private,
1604 IN UINTN DeviceIndex,
1605 IN UINT16 Port,
1606 IN UINT16 PortMultiplier,
1607 IN UINT8 FisIndex,
1608 IN ATA_IDENTIFY_DATA *IdentifyData
1609 )
1610 {
1611 PEI_AHCI_ATA_DEVICE_DATA *DeviceData;
1612 EFI_STATUS Status;
1613
1614 DeviceData = AllocateZeroPool (sizeof (PEI_AHCI_ATA_DEVICE_DATA));
1615 if (DeviceData == NULL) {
1616 return EFI_OUT_OF_RESOURCES;
1617 }
1618
1619 if (IdentifyData != NULL) {
1620 DeviceData->IdentifyData = AllocateCopyPool (sizeof (ATA_IDENTIFY_DATA), IdentifyData);
1621 if (DeviceData->IdentifyData == NULL) {
1622 return EFI_OUT_OF_RESOURCES;
1623 }
1624 }
1625
1626 DeviceData->Signature = AHCI_PEI_ATA_DEVICE_DATA_SIGNATURE;
1627 DeviceData->Port = Port;
1628 DeviceData->PortMultiplier = PortMultiplier;
1629 DeviceData->FisIndex = FisIndex;
1630 DeviceData->DeviceIndex = DeviceIndex;
1631 DeviceData->Private = Private;
1632
1633 Status = IdentifyAtaDevice (DeviceData);
1634 if (EFI_ERROR (Status)) {
1635 return Status;
1636 }
1637
1638 if (DeviceData->TrustComputing) {
1639 Private->TrustComputingDevices++;
1640 DeviceData->TrustComputingDeviceIndex = Private->TrustComputingDevices;
1641 }
1642
1643 Private->ActiveDevices++;
1644 InsertTailList (&Private->DeviceList, &DeviceData->Link);
1645
1646 return EFI_SUCCESS;
1647 }
1648
1649 /**
1650 Initialize ATA host controller at AHCI mode.
1651
1652 The function is designed to initialize ATA host controller.
1653
1654 @param[in,out] Private A pointer to the PEI_AHCI_CONTROLLER_PRIVATE_DATA instance.
1655
1656 @retval EFI_SUCCESS The ATA AHCI controller is initialized successfully.
1657 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete while initializing
1658 the controller.
1659 @retval Others A device error occurred while initializing the
1660 controller.
1661
1662 **/
1663 EFI_STATUS
1664 AhciModeInitialization (
1665 IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private
1666 )
1667 {
1668 EFI_STATUS Status;
1669 UINTN AhciBar;
1670 UINT32 Capability;
1671 UINT32 Value;
1672 UINT8 MaxPortNumber;
1673 UINT32 PortImplementBitMap;
1674 UINT32 PortInitializeBitMap;
1675 EFI_AHCI_REGISTERS *AhciRegisters;
1676 UINT8 PortIndex;
1677 UINT8 Port;
1678 DATA_64 Data64;
1679 UINT32 Data;
1680 UINT32 Offset;
1681 UINT32 PhyDetectDelay;
1682 UINTN DeviceIndex;
1683 ATA_IDENTIFY_DATA IdentifyData;
1684
1685 AhciBar = Private->MmioBase;
1686
1687 Status = AhciReset (AhciBar, AHCI_PEI_RESET_TIMEOUT);
1688 if (EFI_ERROR (Status)) {
1689 DEBUG ((DEBUG_ERROR, "%a: AHCI HBA reset failed with %r.\n", __FUNCTION__, Status));
1690 return EFI_DEVICE_ERROR;
1691 }
1692
1693 //
1694 // Collect AHCI controller information
1695 //
1696 Capability = AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1697
1698 //
1699 // Make sure that GHC.AE bit is set before accessing any AHCI registers.
1700 //
1701 Value = AhciReadReg (AhciBar, AHCI_GHC_OFFSET);
1702 if ((Value & AHCI_GHC_ENABLE) == 0) {
1703 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1704 }
1705
1706 Status = AhciCreateTransferDescriptor (Private);
1707 if (EFI_ERROR (Status)) {
1708 DEBUG ((
1709 DEBUG_ERROR,
1710 "%a: Transfer-related data allocation failed with %r.\n",
1711 __FUNCTION__,
1712 Status
1713 ));
1714 return EFI_OUT_OF_RESOURCES;
1715 }
1716
1717 //
1718 // Get the number of command slots per port supported by this HBA.
1719 //
1720 MaxPortNumber = (UINT8)((Capability & 0x1F) + 1);
1721
1722 //
1723 // Get the bit map of those ports exposed by this HBA.
1724 // It indicates which ports that the HBA supports are available for software
1725 // to use.
1726 //
1727 PortImplementBitMap = AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1728
1729 //
1730 // Get the number of ports that actually needed to be initialized.
1731 //
1732 MaxPortNumber = MIN (MaxPortNumber, (UINT8)(UINTN)(HighBitSet32 (PortImplementBitMap) + 1));
1733 MaxPortNumber = MIN (MaxPortNumber, AhciGetNumberOfPortsFromMap (Private->PortBitMap));
1734
1735 PortInitializeBitMap = Private->PortBitMap & PortImplementBitMap;
1736 AhciRegisters = &Private->AhciRegisters;
1737 DeviceIndex = 0;
1738 //
1739 // Enumerate ATA ports
1740 //
1741 for (PortIndex = 1; PortIndex <= MaxPortNumber; PortIndex++) {
1742 Status = AhciGetPortFromMap (PortInitializeBitMap, PortIndex, &Port);
1743 if (EFI_ERROR (Status)) {
1744 //
1745 // No more available port, just break out of the loop.
1746 //
1747 break;
1748 }
1749
1750 if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
1751 //
1752 // Initialize FIS Base Address Register and Command List Base Address
1753 // Register for use.
1754 //
1755 Data64.Uint64 = (UINTN)(AhciRegisters->AhciRFis) +
1756 sizeof (EFI_AHCI_RECEIVED_FIS) * (PortIndex - 1);
1757 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
1758 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1759 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
1760 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1761
1762 Data64.Uint64 = (UINTN)(AhciRegisters->AhciCmdList);
1763 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
1764 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Lower32);
1765 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
1766 AhciWriteReg (AhciBar, Offset, Data64.Uint32.Upper32);
1767
1768 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1769 Data = AhciReadReg (AhciBar, Offset);
1770 if ((Data & AHCI_PORT_CMD_CPD) != 0) {
1771 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_POD);
1772 }
1773
1774 if ((Capability & AHCI_CAP_SSS) != 0) {
1775 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_SUD);
1776 }
1777
1778 //
1779 // Disable aggressive power management.
1780 //
1781 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SCTL;
1782 AhciOrReg (AhciBar, Offset, AHCI_PORT_SCTL_IPM_INIT);
1783 //
1784 // Disable the reporting of the corresponding interrupt to system software.
1785 //
1786 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IE;
1787 AhciAndReg (AhciBar, Offset, 0);
1788
1789 //
1790 // Enable FIS Receive DMA engine for the first D2H FIS.
1791 //
1792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1793 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
1794
1795 //
1796 // Wait no longer than 15 ms to wait the Phy to detect the presence of a device.
1797 //
1798 PhyDetectDelay = AHCI_BUS_PHY_DETECT_TIMEOUT;
1799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SSTS;
1800 do {
1801 Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_SSTS_DET_MASK;
1802 if ((Data == AHCI_PORT_SSTS_DET_PCE) || (Data == AHCI_PORT_SSTS_DET)) {
1803 break;
1804 }
1805
1806 MicroSecondDelay (1000);
1807 PhyDetectDelay--;
1808 } while (PhyDetectDelay > 0);
1809
1810 if (PhyDetectDelay == 0) {
1811 //
1812 // No device detected at this port.
1813 // Clear PxCMD.SUD for those ports at which there are no device present.
1814 //
1815 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1816 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_SUD));
1817 DEBUG ((DEBUG_ERROR, "%a: No device detected at Port %d.\n", __FUNCTION__, Port));
1818 continue;
1819 }
1820
1821 //
1822 // According to SATA1.0a spec section 5.2, we need to wait for PxTFD.BSY and PxTFD.DRQ
1823 // and PxTFD.ERR to be zero. The maximum wait time is 16s which is defined at ATA spec.
1824 //
1825 PhyDetectDelay = 16 * 1000;
1826 do {
1827 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
1828 if (AhciReadReg (AhciBar, Offset) != 0) {
1829 AhciWriteReg (AhciBar, Offset, AhciReadReg (AhciBar, Offset));
1830 }
1831
1832 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1833
1834 Data = AhciReadReg (AhciBar, Offset) & AHCI_PORT_TFD_MASK;
1835 if (Data == 0) {
1836 break;
1837 }
1838
1839 MicroSecondDelay (1000);
1840 PhyDetectDelay--;
1841 } while (PhyDetectDelay > 0);
1842
1843 if (PhyDetectDelay == 0) {
1844 DEBUG ((
1845 DEBUG_ERROR,
1846 "%a: Port %d device presence detected but phy not ready (TFD=0x%x).\n",
1847 __FUNCTION__,
1848 Port,
1849 Data
1850 ));
1851 continue;
1852 }
1853
1854 //
1855 // When the first D2H register FIS is received, the content of PxSIG register is updated.
1856 //
1857 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SIG;
1858 Status = AhciWaitMmioSet (
1859 AhciBar,
1860 Offset,
1861 0x0000FFFF,
1862 0x00000101,
1863 160000000
1864 );
1865 if (EFI_ERROR (Status)) {
1866 DEBUG ((
1867 DEBUG_ERROR,
1868 "%a: Error occurred when waiting for the first D2H register FIS - %r\n",
1869 __FUNCTION__,
1870 Status
1871 ));
1872 continue;
1873 }
1874
1875 Data = AhciReadReg (AhciBar, Offset);
1876 if ((Data & AHCI_ATAPI_SIG_MASK) == AHCI_ATA_DEVICE_SIG) {
1877 Status = AhciIdentify (Private, Port, 0, PortIndex - 1, &IdentifyData);
1878 if (EFI_ERROR (Status)) {
1879 DEBUG ((DEBUG_ERROR, "%a: AhciIdentify() failed with %r\n", __FUNCTION__, Status));
1880 continue;
1881 }
1882
1883 DEBUG ((DEBUG_INFO, "%a: ATA hard disk found on Port %d.\n", __FUNCTION__, Port));
1884 } else {
1885 continue;
1886 }
1887
1888 //
1889 // Found an ATA hard disk device, add it into the device list.
1890 //
1891 DeviceIndex++;
1892 CreateNewDevice (
1893 Private,
1894 DeviceIndex,
1895 Port,
1896 0xFFFF,
1897 PortIndex - 1,
1898 &IdentifyData
1899 );
1900 }
1901 }
1902
1903 return EFI_SUCCESS;
1904 }
1905
1906 /**
1907 Transfer data from ATA device.
1908
1909 This function performs one ATA pass through transaction to transfer data from/to
1910 ATA device. It chooses the appropriate ATA command and protocol to invoke PassThru
1911 interface of ATA pass through.
1912
1913 @param[in] DeviceData A pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
1914 @param[in,out] Buffer The pointer to the current transaction buffer.
1915 @param[in] StartLba The starting logical block address to be accessed.
1916 @param[in] TransferLength The block number or sector count of the transfer.
1917 @param[in] IsWrite Indicates whether it is a write operation.
1918
1919 @retval EFI_SUCCESS The data transfer is complete successfully.
1920 @return others Some error occurs when transferring data.
1921
1922 **/
1923 EFI_STATUS
1924 TransferAtaDevice (
1925 IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData,
1926 IN OUT VOID *Buffer,
1927 IN EFI_LBA StartLba,
1928 IN UINT32 TransferLength,
1929 IN BOOLEAN IsWrite
1930 )
1931 {
1932 PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private;
1933 EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru;
1934 EFI_ATA_COMMAND_BLOCK Acb;
1935 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
1936
1937 Private = DeviceData->Private;
1938 AtaPassThru = &Private->AtaPassThruPpi;
1939
1940 //
1941 // Ensure Lba48Bit and IsWrite are valid boolean values
1942 //
1943 ASSERT ((UINTN)DeviceData->Lba48Bit < 2);
1944 ASSERT ((UINTN)IsWrite < 2);
1945 if (((UINTN)DeviceData->Lba48Bit >= 2) ||
1946 ((UINTN)IsWrite >= 2))
1947 {
1948 return EFI_INVALID_PARAMETER;
1949 }
1950
1951 //
1952 // Prepare for ATA command block.
1953 //
1954 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
1955 Acb.AtaCommand = mAtaCommands[DeviceData->Lba48Bit][IsWrite];
1956 Acb.AtaSectorNumber = (UINT8)StartLba;
1957 Acb.AtaCylinderLow = (UINT8)RShiftU64 (StartLba, 8);
1958 Acb.AtaCylinderHigh = (UINT8)RShiftU64 (StartLba, 16);
1959 Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 |
1960 (DeviceData->PortMultiplier == 0xFFFF ?
1961 0 : (DeviceData->PortMultiplier << 4)));
1962 Acb.AtaSectorCount = (UINT8)TransferLength;
1963 if (DeviceData->Lba48Bit) {
1964 Acb.AtaSectorNumberExp = (UINT8)RShiftU64 (StartLba, 24);
1965 Acb.AtaCylinderLowExp = (UINT8)RShiftU64 (StartLba, 32);
1966 Acb.AtaCylinderHighExp = (UINT8)RShiftU64 (StartLba, 40);
1967 Acb.AtaSectorCountExp = (UINT8)(TransferLength >> 8);
1968 } else {
1969 Acb.AtaDeviceHead = (UINT8)(Acb.AtaDeviceHead | RShiftU64 (StartLba, 24));
1970 }
1971
1972 //
1973 // Prepare for ATA pass through packet.
1974 //
1975 ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
1976 if (IsWrite) {
1977 Packet.OutDataBuffer = Buffer;
1978 Packet.OutTransferLength = TransferLength;
1979 } else {
1980 Packet.InDataBuffer = Buffer;
1981 Packet.InTransferLength = TransferLength;
1982 }
1983
1984 Packet.Asb = NULL;
1985 Packet.Acb = &Acb;
1986 Packet.Protocol = mAtaPassThruCmdProtocols[IsWrite];
1987 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
1988 //
1989 // |------------------------|-----------------|
1990 // | ATA PIO Transfer Mode | Transfer Rate |
1991 // |------------------------|-----------------|
1992 // | PIO Mode 0 | 3.3Mbytes/sec |
1993 // |------------------------|-----------------|
1994 // | PIO Mode 1 | 5.2Mbytes/sec |
1995 // |------------------------|-----------------|
1996 // | PIO Mode 2 | 8.3Mbytes/sec |
1997 // |------------------------|-----------------|
1998 // | PIO Mode 3 | 11.1Mbytes/sec |
1999 // |------------------------|-----------------|
2000 // | PIO Mode 4 | 16.6Mbytes/sec |
2001 // |------------------------|-----------------|
2002 //
2003 // As AtaBus is used to manage ATA devices, we have to use the lowest transfer
2004 // rate to calculate the possible maximum timeout value for each read/write
2005 // operation. The timout value is rounded up to nearest integar and here an
2006 // additional 30s is added to follow ATA spec in which it mentioned that the
2007 // device may take up to 30s to respond commands in the Standby/Idle mode.
2008 //
2009 // Calculate the maximum timeout value for PIO read/write operation.
2010 //
2011 Packet.Timeout = TIMER_PERIOD_SECONDS (
2012 DivU64x32 (
2013 MultU64x32 (TransferLength, DeviceData->Media.BlockSize),
2014 3300000
2015 ) + 31
2016 );
2017
2018 return AtaPassThru->PassThru (
2019 AtaPassThru,
2020 DeviceData->Port,
2021 DeviceData->PortMultiplier,
2022 &Packet
2023 );
2024 }
2025
2026 /**
2027 Trust transfer data from/to ATA device.
2028
2029 This function performs one ATA pass through transaction to do a trust transfer
2030 from/to ATA device. It chooses the appropriate ATA command and protocol to invoke
2031 PassThru interface of ATA pass through.
2032
2033 @param[in] DeviceData Pointer to PEI_AHCI_ATA_DEVICE_DATA structure.
2034 @param[in,out] Buffer The pointer to the current transaction buffer.
2035 @param[in] SecurityProtocolId
2036 The value of the "Security Protocol" parameter
2037 of the security protocol command to be sent.
2038 @param[in] SecurityProtocolSpecificData
2039 The value of the "Security Protocol Specific"
2040 parameter of the security protocol command to
2041 be sent.
2042 @param[in] TransferLength The block number or sector count of the transfer.
2043 @param[in] IsTrustSend Indicates whether it is a trust send operation
2044 or not.
2045 @param[in] Timeout The timeout, in 100ns units, to use for the execution
2046 of the security protocol command. A Timeout value
2047 of 0 means that this function will wait indefinitely
2048 for the security protocol command to execute. If
2049 Timeout is greater than zero, then this function
2050 will return EFI_TIMEOUT if the time required to
2051 execute the receive data command is greater than
2052 Timeout.
2053 @param[out] TransferLengthOut
2054 A pointer to a buffer to store the size in bytes
2055 of the data written to the buffer. Ignore it when
2056 IsTrustSend is TRUE.
2057
2058 @retval EFI_SUCCESS The data transfer is complete successfully.
2059 @return others Some error occurs when transferring data.
2060
2061 **/
2062 EFI_STATUS
2063 TrustTransferAtaDevice (
2064 IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData,
2065 IN OUT VOID *Buffer,
2066 IN UINT8 SecurityProtocolId,
2067 IN UINT16 SecurityProtocolSpecificData,
2068 IN UINTN TransferLength,
2069 IN BOOLEAN IsTrustSend,
2070 IN UINT64 Timeout,
2071 OUT UINTN *TransferLengthOut
2072 )
2073 {
2074 PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private;
2075 EDKII_PEI_ATA_PASS_THRU_PPI *AtaPassThru;
2076 EFI_ATA_COMMAND_BLOCK Acb;
2077 EFI_ATA_PASS_THRU_COMMAND_PACKET Packet;
2078 EFI_STATUS Status;
2079 VOID *NewBuffer;
2080
2081 Private = DeviceData->Private;
2082 AtaPassThru = &Private->AtaPassThruPpi;
2083
2084 //
2085 // Ensure IsTrustSend are valid boolean values
2086 //
2087 ASSERT ((UINTN)IsTrustSend < 2);
2088 if ((UINTN)IsTrustSend >= 2) {
2089 return EFI_INVALID_PARAMETER;
2090 }
2091
2092 //
2093 // Prepare for ATA command block.
2094 //
2095 ZeroMem (&Acb, sizeof (EFI_ATA_COMMAND_BLOCK));
2096 if (TransferLength == 0) {
2097 Acb.AtaCommand = ATA_CMD_TRUST_NON_DATA;
2098 } else {
2099 Acb.AtaCommand = mAtaTrustCommands[IsTrustSend];
2100 }
2101
2102 Acb.AtaFeatures = SecurityProtocolId;
2103 Acb.AtaSectorCount = (UINT8)(TransferLength / 512);
2104 Acb.AtaSectorNumber = (UINT8)((TransferLength / 512) >> 8);
2105 //
2106 // NOTE: ATA Spec has no explicitly definition for Security Protocol Specific layout.
2107 // Here use big endian for Cylinder register.
2108 //
2109 Acb.AtaCylinderHigh = (UINT8)SecurityProtocolSpecificData;
2110 Acb.AtaCylinderLow = (UINT8)(SecurityProtocolSpecificData >> 8);
2111 Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 |
2112 (DeviceData->PortMultiplier == 0xFFFF ?
2113 0 : (DeviceData->PortMultiplier << 4)));
2114
2115 //
2116 // Prepare for ATA pass through packet.
2117 //
2118 ZeroMem (&Packet, sizeof (EFI_ATA_PASS_THRU_COMMAND_PACKET));
2119 if (TransferLength == 0) {
2120 Packet.InTransferLength = 0;
2121 Packet.OutTransferLength = 0;
2122 Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
2123 } else if (IsTrustSend) {
2124 //
2125 // Check the alignment of the incoming buffer prior to invoking underlying
2126 // ATA PassThru PPI.
2127 //
2128 if ((AtaPassThru->Mode->IoAlign > 1) &&
2129 !IS_ALIGNED (Buffer, AtaPassThru->Mode->IoAlign))
2130 {
2131 NewBuffer = AllocateAlignedPages (
2132 EFI_SIZE_TO_PAGES (TransferLength),
2133 AtaPassThru->Mode->IoAlign
2134 );
2135 if (NewBuffer == NULL) {
2136 return EFI_OUT_OF_RESOURCES;
2137 }
2138
2139 CopyMem (NewBuffer, Buffer, TransferLength);
2140 Buffer = NewBuffer;
2141 }
2142
2143 Packet.OutDataBuffer = Buffer;
2144 Packet.OutTransferLength = (UINT32)TransferLength;
2145 Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2146 } else {
2147 Packet.InDataBuffer = Buffer;
2148 Packet.InTransferLength = (UINT32)TransferLength;
2149 Packet.Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2150 }
2151
2152 Packet.Asb = NULL;
2153 Packet.Acb = &Acb;
2154 Packet.Timeout = Timeout;
2155 Packet.Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
2156
2157 Status = AtaPassThru->PassThru (
2158 AtaPassThru,
2159 DeviceData->Port,
2160 DeviceData->PortMultiplier,
2161 &Packet
2162 );
2163 if (TransferLengthOut != NULL) {
2164 if (!IsTrustSend) {
2165 *TransferLengthOut = Packet.InTransferLength;
2166 }
2167 }
2168
2169 return Status;
2170 }