TianoCore EDK2 master
Loading...
Searching...
No Matches
SdBlockIoPei.c
Go to the documentation of this file.
1
8#include "SdBlockIoPei.h"
9
10//
11// Template for SD HC Slot Data.
12//
13SD_PEIM_HC_SLOT gSdHcSlotTemplate = {
14 SD_PEIM_SLOT_SIG, // Signature
15 { // Media
17 FALSE,
18 TRUE,
19 FALSE,
20 0x200,
21 0
22 },
23 0, // SdHcBase
24 { // Capability
25 0,
26 },
27 { // Csd
28 0,
29 },
30 TRUE, // SectorAddressing
31 NULL // Private
32};
33
34//
35// Template for SD HC Private Data.
36//
37SD_PEIM_HC_PRIVATE_DATA gSdHcPrivateTemplate = {
38 SD_PEIM_SIG, // Signature
39 NULL, // Pool
40 { // BlkIoPpi
44 },
45 { // BlkIo2Ppi
46 EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION,
50 },
51 { // BlkIoPpiList
52 EFI_PEI_PPI_DESCRIPTOR_PPI,
53 &gEfiPeiVirtualBlockIoPpiGuid,
54 NULL
55 },
56 { // BlkIo2PpiList
57 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
58 &gEfiPeiVirtualBlockIo2PpiGuid,
59 NULL
60 },
61 {
62 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
63 &gEfiEndOfPeiSignalPpiGuid,
65 },
66 { // Slot
67 {
68 0,
69 },
70 {
71 0,
72 },
73 {
74 0,
75 },
76 {
77 0,
78 },
79 {
80 0,
81 },
82 {
83 0,
84 }
85 },
86 0, // SlotNum
87 0 // TotalBlkIoDevices
88};
89
110EFIAPI
112 IN EFI_PEI_SERVICES **PeiServices,
114 OUT UINTN *NumberBlockDevices
115 )
116{
118
119 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This);
120 *NumberBlockDevices = Private->TotalBlkIoDevices;
121 return EFI_SUCCESS;
122}
123
166EFIAPI
168 IN EFI_PEI_SERVICES **PeiServices,
170 IN UINTN DeviceIndex,
171 OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
172 )
173{
175
176 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This);
177
178 if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices) || (DeviceIndex > SD_PEIM_MAX_SLOTS)) {
179 return EFI_INVALID_PARAMETER;
180 }
181
182 MediaInfo->DeviceType = SD;
183 MediaInfo->MediaPresent = TRUE;
184 MediaInfo->LastBlock = (UINTN)Private->Slot[DeviceIndex - 1].Media.LastBlock;
185 MediaInfo->BlockSize = Private->Slot[DeviceIndex - 1].Media.BlockSize;
186
187 return EFI_SUCCESS;
188}
189
225EFIAPI
227 IN EFI_PEI_SERVICES **PeiServices,
229 IN UINTN DeviceIndex,
230 IN EFI_PEI_LBA StartLBA,
231 IN UINTN BufferSize,
232 OUT VOID *Buffer
233 )
234{
235 EFI_STATUS Status;
236 UINT32 BlockSize;
237 UINTN NumberOfBlocks;
239 UINTN Remaining;
240 UINT32 MaxBlock;
241
242 Status = EFI_SUCCESS;
243 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS (This);
244
245 //
246 // Check parameters
247 //
248 if (Buffer == NULL) {
249 return EFI_INVALID_PARAMETER;
250 }
251
252 if (BufferSize == 0) {
253 return EFI_SUCCESS;
254 }
255
256 if ((DeviceIndex == 0) || (DeviceIndex > Private->TotalBlkIoDevices) || (DeviceIndex > SD_PEIM_MAX_SLOTS)) {
257 return EFI_INVALID_PARAMETER;
258 }
259
260 BlockSize = Private->Slot[DeviceIndex - 1].Media.BlockSize;
261 if (BufferSize % BlockSize != 0) {
262 return EFI_BAD_BUFFER_SIZE;
263 }
264
265 if (StartLBA > Private->Slot[DeviceIndex - 1].Media.LastBlock) {
266 return EFI_INVALID_PARAMETER;
267 }
268
269 NumberOfBlocks = BufferSize / BlockSize;
270
271 //
272 // Start to execute data transfer. The max block number in single cmd is 65535 blocks.
273 //
274 Remaining = NumberOfBlocks;
275 MaxBlock = 0xFFFF;
276
277 while (Remaining > 0) {
278 if (Remaining <= MaxBlock) {
279 NumberOfBlocks = Remaining;
280 } else {
281 NumberOfBlocks = MaxBlock;
282 }
283
284 BufferSize = NumberOfBlocks * BlockSize;
285 if (NumberOfBlocks != 1) {
286 Status = SdPeimRwMultiBlocks (&Private->Slot[DeviceIndex - 1], StartLBA, BlockSize, Buffer, BufferSize, TRUE);
287 } else {
288 Status = SdPeimRwSingleBlock (&Private->Slot[DeviceIndex - 1], StartLBA, BlockSize, Buffer, BufferSize, TRUE);
289 }
290
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294
295 StartLBA += NumberOfBlocks;
296 Buffer = (UINT8 *)Buffer + BufferSize;
297 Remaining -= NumberOfBlocks;
298 }
299
300 return Status;
301}
302
323EFIAPI
325 IN EFI_PEI_SERVICES **PeiServices,
327 OUT UINTN *NumberBlockDevices
328 )
329{
331
332 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This);
333 *NumberBlockDevices = Private->TotalBlkIoDevices;
334
335 return EFI_SUCCESS;
336}
337
380EFIAPI
382 IN EFI_PEI_SERVICES **PeiServices,
384 IN UINTN DeviceIndex,
386 )
387{
388 EFI_STATUS Status;
391
392 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This);
393
395 PeiServices,
396 &Private->BlkIoPpi,
397 DeviceIndex,
398 &Media
399 );
400 if (EFI_ERROR (Status)) {
401 return Status;
402 }
403
404 CopyMem (MediaInfo, &(Private->Slot[DeviceIndex - 1].Media), sizeof (EFI_PEI_BLOCK_IO2_MEDIA));
405 return EFI_SUCCESS;
406}
407
443EFIAPI
445 IN EFI_PEI_SERVICES **PeiServices,
447 IN UINTN DeviceIndex,
448 IN EFI_PEI_LBA StartLBA,
449 IN UINTN BufferSize,
450 OUT VOID *Buffer
451 )
452{
453 EFI_STATUS Status;
455
456 Status = EFI_SUCCESS;
457 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This);
458
459 Status = SdBlockIoPeimReadBlocks (
460 PeiServices,
461 &Private->BlkIoPpi,
462 DeviceIndex,
463 StartLBA,
464 BufferSize,
465 Buffer
466 );
467 return Status;
468}
469
482EFIAPI
484 IN EFI_PEI_SERVICES **PeiServices,
485 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
486 IN VOID *Ppi
487 )
488{
490
491 Private = GET_SD_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor);
492
493 if ((Private->Pool != NULL) && (Private->Pool->Head != NULL)) {
494 SdPeimFreeMemPool (Private->Pool);
495 }
496
497 return EFI_SUCCESS;
498}
499
511EFIAPI
513 IN EFI_PEI_FILE_HANDLE FileHandle,
514 IN CONST EFI_PEI_SERVICES **PeiServices
515 )
516{
517 EFI_STATUS Status;
520 UINT32 Index;
521 UINTN *MmioBase;
522 UINT8 BarNum;
523 UINT8 SlotNum;
524 UINT8 Controller;
525 UINT64 Capacity;
526 SD_HC_SLOT_CAP Capability;
527 SD_PEIM_HC_SLOT *Slot;
528 SD_CSD *Csd;
529 SD_CSD2 *Csd2;
530 UINT32 CSize;
531 UINT32 CSizeMul;
532 UINT32 ReadBlLen;
533
534 //
535 // Shadow this PEIM to run from memory
536 //
537 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
538 return EFI_SUCCESS;
539 }
540
541 //
542 // locate Sd host controller PPI
543 //
544 Status = PeiServicesLocatePpi (
545 &gEdkiiPeiSdMmcHostControllerPpiGuid,
546 0,
547 NULL,
548 (VOID **)&SdMmcHcPpi
549 );
550 if (EFI_ERROR (Status)) {
551 return EFI_DEVICE_ERROR;
552 }
553
554 IoMmuInit ();
555
556 Controller = 0;
557 MmioBase = NULL;
558 while (TRUE) {
559 Status = SdMmcHcPpi->GetSdMmcHcMmioBar (SdMmcHcPpi, Controller, &MmioBase, &BarNum);
560 //
561 // When status is error, meant no controller is found
562 //
563 if (EFI_ERROR (Status)) {
564 break;
565 }
566
567 if (BarNum == 0) {
568 Controller++;
569 continue;
570 }
571
572 Private = AllocateCopyPool (sizeof (SD_PEIM_HC_PRIVATE_DATA), &gSdHcPrivateTemplate);
573 if (Private == NULL) {
574 Status = EFI_OUT_OF_RESOURCES;
575 break;
576 }
577
578 Private->BlkIoPpiList.Ppi = (VOID *)&Private->BlkIoPpi;
579 Private->BlkIo2PpiList.Ppi = (VOID *)&Private->BlkIo2Ppi;
580 //
581 // Initialize the memory pool which will be used in all transactions.
582 //
583 Status = SdPeimInitMemPool (Private);
584 if (EFI_ERROR (Status)) {
585 Status = EFI_OUT_OF_RESOURCES;
586 break;
587 }
588
589 for (Index = 0; Index < BarNum; Index++) {
590 Status = SdPeimHcGetCapability (MmioBase[Index], &Capability);
591 if (EFI_ERROR (Status)) {
592 continue;
593 }
594
595 if (Capability.SlotType != 0x1) {
596 DEBUG ((DEBUG_INFO, "The slot at 0x%x is not embedded slot type\n", MmioBase[Index]));
597 Status = EFI_UNSUPPORTED;
598 continue;
599 }
600
601 Status = SdPeimHcReset (MmioBase[Index]);
602 if (EFI_ERROR (Status)) {
603 continue;
604 }
605
606 Status = SdPeimHcCardDetect (MmioBase[Index]);
607 if (EFI_ERROR (Status)) {
608 continue;
609 }
610
611 Status = SdPeimHcInitHost (MmioBase[Index]);
612 if (EFI_ERROR (Status)) {
613 continue;
614 }
615
616 SlotNum = Private->SlotNum;
617 Slot = &Private->Slot[SlotNum];
618 CopyMem (Slot, &gSdHcSlotTemplate, sizeof (SD_PEIM_HC_SLOT));
619 Slot->Private = Private;
620 Slot->SdHcBase = MmioBase[Index];
621 CopyMem (&Slot->Capability, &Capability, sizeof (Capability));
622
623 Status = SdPeimIdentification (Slot);
624 if (EFI_ERROR (Status)) {
625 continue;
626 }
627
628 Csd = &Slot->Csd;
629 if (Csd->CsdStructure == 0) {
630 Slot->SectorAddressing = FALSE;
631 CSize = (Csd->CSizeHigh << 2 | Csd->CSizeLow) + 1;
632 CSizeMul = (1 << (Csd->CSizeMul + 2));
633 ReadBlLen = (1 << (Csd->ReadBlLen));
634 Capacity = MultU64x32 (MultU64x32 ((UINT64)CSize, CSizeMul), ReadBlLen);
635 } else {
636 Slot->SectorAddressing = TRUE;
637 Csd2 = (SD_CSD2 *)(VOID *)Csd;
638 CSize = (Csd2->CSizeHigh << 16 | Csd2->CSizeLow) + 1;
639 Capacity = MultU64x32 ((UINT64)CSize, SIZE_512KB);
640 }
641
642 Slot->Media.LastBlock = DivU64x32 (Capacity, Slot->Media.BlockSize) - 1;
643
644 Private->TotalBlkIoDevices++;
645 Private->SlotNum++;
646 }
647
648 Controller++;
649 if (!EFI_ERROR (Status)) {
650 PeiServicesInstallPpi (&Private->BlkIoPpiList);
651 PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
652 } else {
653 if (Private->Pool->Head != NULL) {
654 SdPeimFreeMemPool (Private->Pool);
655 }
656 }
657 }
658
659 return EFI_SUCCESS;
660}
UINT64 UINTN
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define MSG_SD_DP
Definition: DevicePath.h:907
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI PeiServicesRegisterForShadow(IN EFI_PEI_FILE_HANDLE FileHandle)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
@ SD
The recovery device is a Secure Digital device.
Definition: BlockIo.h:51
UINT64 EFI_PEI_LBA
Definition: BlockIo.h:41
VOID IoMmuInit(OUT EDKII_IOMMU_PPI **IoMmu)
Definition: DmaMem.c:238
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
EFI_STATUS EFIAPI SdBlockIoPeimGetDeviceNo(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, OUT UINTN *NumberBlockDevices)
Definition: SdBlockIoPei.c:111
EFI_STATUS EFIAPI SdBlockIoPeimGetMediaInfo2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO2_MEDIA *MediaInfo)
Definition: SdBlockIoPei.c:381
EFI_STATUS EFIAPI InitializeSdBlockIoPeim(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: SdBlockIoPei.c:512
EFI_STATUS EFIAPI SdBlockIoPeimReadBlocks2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
Definition: SdBlockIoPei.c:444
EFI_STATUS EFIAPI SdBlockIoPeimGetMediaInfo(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo)
Definition: SdBlockIoPei.c:167
EFI_STATUS EFIAPI SdBlockIoPeimEndOfPei(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi)
Definition: SdBlockIoPei.c:483
EFI_STATUS EFIAPI SdBlockIoPeimGetDeviceNo2(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI *This, OUT UINTN *NumberBlockDevices)
Definition: SdBlockIoPei.c:324
EFI_STATUS EFIAPI SdBlockIoPeimReadBlocks(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, IN UINTN DeviceIndex, IN EFI_PEI_LBA StartLBA, IN UINTN BufferSize, OUT VOID *Buffer)
Definition: SdBlockIoPei.c:226
EFI_STATUS SdPeimFreeMemPool(IN SD_PEIM_MEM_POOL *Pool)
Definition: SdHcMem.c:263
EFI_STATUS SdPeimInitMemPool(IN SD_PEIM_HC_PRIVATE_DATA *Private)
Definition: SdHcMem.c:223
EFI_STATUS SdPeimHcCardDetect(IN UINTN Bar)
Definition: SdHci.c:414
EFI_STATUS SdPeimHcInitHost(IN UINTN Bar)
Definition: SdHci.c:868
EFI_STATUS SdPeimRwMultiBlocks(IN SD_PEIM_HC_SLOT *Slot, IN EFI_LBA Lba, IN UINT32 BlockSize, IN VOID *Buffer, IN UINTN BufferSize, IN BOOLEAN IsRead)
Definition: SdHci.c:2435
EFI_STATUS SdPeimHcReset(IN UINTN Bar)
Definition: SdHci.c:300
EFI_STATUS SdPeimIdentification(IN SD_PEIM_HC_SLOT *Slot)
Definition: SdHci.c:2803
EFI_STATUS SdPeimRwSingleBlock(IN SD_PEIM_HC_SLOT *Slot, IN EFI_LBA Lba, IN UINT32 BlockSize, IN VOID *Buffer, IN UINTN BufferSize, IN BOOLEAN IsRead)
Definition: SdHci.c:2362
EFI_STATUS SdPeimHcGetCapability(IN UINTN Bar, OUT SD_HC_SLOT_CAP *Capability)
Definition: SdHci.c:382
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_PEI_LBA LastBlock
Definition: BlockIo2.h:64
Definition: Sd.h:120
Definition: Sd.h:78