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