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