3 Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
8 #include "EmmcBlockIoPei.h"
11 // Template for EMMC HC Slot Data.
13 EMMC_PEIM_HC_SLOT gEmmcHcSlotTemplate
= {
14 EMMC_PEIM_SLOT_SIG
, // Signature
102 TRUE
, // SectorAddressing
107 // Template for EMMC HC Private Data.
109 EMMC_PEIM_HC_PRIVATE_DATA gEmmcHcPrivateTemplate
= {
110 EMMC_PEIM_SIG
, // Signature
113 EmmcBlockIoPeimGetDeviceNo
,
114 EmmcBlockIoPeimGetMediaInfo
,
115 EmmcBlockIoPeimReadBlocks
118 EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION
,
119 EmmcBlockIoPeimGetDeviceNo2
,
120 EmmcBlockIoPeimGetMediaInfo2
,
121 EmmcBlockIoPeimReadBlocks2
124 EFI_PEI_PPI_DESCRIPTOR_PPI
,
125 &gEfiPeiVirtualBlockIoPpiGuid
,
129 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
130 &gEfiPeiVirtualBlockIo2PpiGuid
,
133 { // EndOfPeiNotifyList
134 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
135 &gEfiEndOfPeiSignalPpiGuid
,
136 EmmcBlockIoPeimEndOfPei
159 0 // TotalBlkIoDevices
162 Gets the count of block I/O devices that one specific block driver detects.
164 This function is used for getting the count of block I/O devices that one
165 specific block driver detects. To the PEI ATAPI driver, it returns the number
166 of all the detected ATAPI devices it detects during the enumeration process.
167 To the PEI legacy floppy driver, it returns the number of all the legacy
168 devices it finds during its enumeration process. If no device is detected,
169 then the function will return zero.
171 @param[in] PeiServices General-purpose services that are available
173 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
175 @param[out] NumberBlockDevices The number of block I/O devices discovered.
177 @retval EFI_SUCCESS The operation performed successfully.
182 EmmcBlockIoPeimGetDeviceNo (
183 IN EFI_PEI_SERVICES
**PeiServices
,
184 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
185 OUT UINTN
*NumberBlockDevices
188 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
190 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
191 *NumberBlockDevices
= Private
->TotalBlkIoDevices
;
196 Gets a block device's media information.
198 This function will provide the caller with the specified block device's media
199 information. If the media changes, calling this function will update the media
200 information accordingly.
202 @param[in] PeiServices General-purpose services that are available to every
204 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
205 @param[in] DeviceIndex Specifies the block device to which the function wants
206 to talk. Because the driver that implements Block I/O
207 PPIs will manage multiple block devices, the PPIs that
208 want to talk to a single device must specify the
209 device index that was assigned during the enumeration
210 process. This index is a number from one to
212 @param[out] MediaInfo The media information of the specified block media.
213 The caller is responsible for the ownership of this
217 The MediaInfo structure describes an enumeration of possible block device
218 types. This enumeration exists because no device paths are actually passed
219 across interfaces that describe the type or class of hardware that is publishing
220 the block I/O interface. This enumeration will allow for policy decisions
221 in the Recovery PEIM, such as "Try to recover from legacy floppy first,
222 LS-120 second, CD-ROM third." If there are multiple partitions abstracted
223 by a given device type, they should be reported in ascending order; this
224 order also applies to nested partitions, such as legacy MBR, where the
225 outermost partitions would have precedence in the reporting order. The
226 same logic applies to systems such as IDE that have precedence relationships
227 like "Master/Slave" or "Primary/Secondary". The master device should be
228 reported first, the slave second.
230 @retval EFI_SUCCESS Media information about the specified block device
231 was obtained successfully.
232 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
238 EmmcBlockIoPeimGetMediaInfo (
239 IN EFI_PEI_SERVICES
**PeiServices
,
240 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
241 IN UINTN DeviceIndex
,
242 OUT EFI_PEI_BLOCK_IO_MEDIA
*MediaInfo
245 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
252 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
254 if ((DeviceIndex
== 0) || (DeviceIndex
> Private
->TotalBlkIoDevices
)) {
255 return EFI_INVALID_PARAMETER
;
260 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
261 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
263 if (Location
== DeviceIndex
) {
273 MediaInfo
->DeviceType
= EMMC
;
274 MediaInfo
->MediaPresent
= TRUE
;
275 MediaInfo
->LastBlock
= (UINTN
)Private
->Slot
[SlotNum
].Media
[MediaNum
].LastBlock
;
276 MediaInfo
->BlockSize
= Private
->Slot
[SlotNum
].Media
[MediaNum
].BlockSize
;
282 Reads the requested number of blocks from the specified block device.
284 The function reads the requested number of blocks from the device. All the
285 blocks are read, or an error is returned. If there is no media in the device,
286 the function returns EFI_NO_MEDIA.
288 @param[in] PeiServices General-purpose services that are available to
290 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
291 @param[in] DeviceIndex Specifies the block device to which the function wants
292 to talk. Because the driver that implements Block I/O
293 PPIs will manage multiple block devices, PPIs that
294 want to talk to a single device must specify the device
295 index that was assigned during the enumeration process.
296 This index is a number from one to NumberBlockDevices.
297 @param[in] StartLBA The starting logical block address (LBA) to read from
299 @param[in] BufferSize The size of the Buffer in bytes. This number must be
300 a multiple of the intrinsic block size of the device.
301 @param[out] Buffer A pointer to the destination buffer for the data.
302 The caller is responsible for the ownership of the
305 @retval EFI_SUCCESS The data was read correctly from the device.
306 @retval EFI_DEVICE_ERROR The device reported an error while attempting
307 to perform the read operation.
308 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
309 valid, or the buffer is not properly aligned.
310 @retval EFI_NO_MEDIA There is no media in the device.
311 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
312 the intrinsic block size of the device.
317 EmmcBlockIoPeimReadBlocks (
318 IN EFI_PEI_SERVICES
**PeiServices
,
319 IN EFI_PEI_RECOVERY_BLOCK_IO_PPI
*This
,
320 IN UINTN DeviceIndex
,
321 IN EFI_PEI_LBA StartLBA
,
328 UINTN NumberOfBlocks
;
329 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
333 UINT8 PartitionConfig
;
338 Status
= EFI_SUCCESS
;
340 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS (This
);
345 if (Buffer
== NULL
) {
346 return EFI_INVALID_PARAMETER
;
349 if (BufferSize
== 0) {
353 if ((DeviceIndex
== 0) || (DeviceIndex
> Private
->TotalBlkIoDevices
)) {
354 return EFI_INVALID_PARAMETER
;
359 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
360 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
362 if (Location
== DeviceIndex
) {
372 BlockSize
= Private
->Slot
[SlotNum
].Media
[MediaNum
].BlockSize
;
373 if (BufferSize
% BlockSize
!= 0) {
374 return EFI_BAD_BUFFER_SIZE
;
377 if (StartLBA
> Private
->Slot
[SlotNum
].Media
[MediaNum
].LastBlock
) {
378 return EFI_INVALID_PARAMETER
;
381 NumberOfBlocks
= BufferSize
/ BlockSize
;
384 // Check if needs to switch partition access.
386 PartitionConfig
= Private
->Slot
[SlotNum
].ExtCsd
.PartitionConfig
;
387 if ((PartitionConfig
& 0x7) != Private
->Slot
[SlotNum
].PartitionType
[MediaNum
]) {
388 PartitionConfig
&= (UINT8
)~0x7;
389 PartitionConfig
|= Private
->Slot
[SlotNum
].PartitionType
[MediaNum
];
390 Status
= EmmcPeimSwitch (
391 &Private
->Slot
[SlotNum
],
393 OFFSET_OF (EMMC_EXT_CSD
, PartitionConfig
),
397 if (EFI_ERROR (Status
)) {
400 Private
->Slot
[SlotNum
].ExtCsd
.PartitionConfig
= PartitionConfig
;
403 // Start to execute data transfer. The max block number in single cmd is 65535 blocks.
405 Remaining
= NumberOfBlocks
;
408 while (Remaining
> 0) {
409 if (Remaining
<= MaxBlock
) {
410 NumberOfBlocks
= Remaining
;
412 NumberOfBlocks
= MaxBlock
;
415 Status
= EmmcPeimSetBlkCount (&Private
->Slot
[SlotNum
], (UINT16
)NumberOfBlocks
);
416 if (EFI_ERROR (Status
)) {
420 BufferSize
= NumberOfBlocks
* BlockSize
;
421 Status
= EmmcPeimRwMultiBlocks (&Private
->Slot
[SlotNum
], StartLBA
, BlockSize
, Buffer
, BufferSize
, TRUE
);
422 if (EFI_ERROR (Status
)) {
426 StartLBA
+= NumberOfBlocks
;
427 Buffer
= (UINT8
*)Buffer
+ BufferSize
;
428 Remaining
-= NumberOfBlocks
;
434 Gets the count of block I/O devices that one specific block driver detects.
436 This function is used for getting the count of block I/O devices that one
437 specific block driver detects. To the PEI ATAPI driver, it returns the number
438 of all the detected ATAPI devices it detects during the enumeration process.
439 To the PEI legacy floppy driver, it returns the number of all the legacy
440 devices it finds during its enumeration process. If no device is detected,
441 then the function will return zero.
443 @param[in] PeiServices General-purpose services that are available
445 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI
447 @param[out] NumberBlockDevices The number of block I/O devices discovered.
449 @retval EFI_SUCCESS The operation performed successfully.
454 EmmcBlockIoPeimGetDeviceNo2 (
455 IN EFI_PEI_SERVICES
**PeiServices
,
456 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
457 OUT UINTN
*NumberBlockDevices
460 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
462 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
463 *NumberBlockDevices
= Private
->TotalBlkIoDevices
;
469 Gets a block device's media information.
471 This function will provide the caller with the specified block device's media
472 information. If the media changes, calling this function will update the media
473 information accordingly.
475 @param[in] PeiServices General-purpose services that are available to every
477 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
478 @param[in] DeviceIndex Specifies the block device to which the function wants
479 to talk. Because the driver that implements Block I/O
480 PPIs will manage multiple block devices, the PPIs that
481 want to talk to a single device must specify the
482 device index that was assigned during the enumeration
483 process. This index is a number from one to
485 @param[out] MediaInfo The media information of the specified block media.
486 The caller is responsible for the ownership of this
490 The MediaInfo structure describes an enumeration of possible block device
491 types. This enumeration exists because no device paths are actually passed
492 across interfaces that describe the type or class of hardware that is publishing
493 the block I/O interface. This enumeration will allow for policy decisions
494 in the Recovery PEIM, such as "Try to recover from legacy floppy first,
495 LS-120 second, CD-ROM third." If there are multiple partitions abstracted
496 by a given device type, they should be reported in ascending order; this
497 order also applies to nested partitions, such as legacy MBR, where the
498 outermost partitions would have precedence in the reporting order. The
499 same logic applies to systems such as IDE that have precedence relationships
500 like "Master/Slave" or "Primary/Secondary". The master device should be
501 reported first, the slave second.
503 @retval EFI_SUCCESS Media information about the specified block device
504 was obtained successfully.
505 @retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
511 EmmcBlockIoPeimGetMediaInfo2 (
512 IN EFI_PEI_SERVICES
**PeiServices
,
513 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
514 IN UINTN DeviceIndex
,
515 OUT EFI_PEI_BLOCK_IO2_MEDIA
*MediaInfo
519 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
520 EFI_PEI_BLOCK_IO_MEDIA Media
;
527 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
529 Status
= EmmcBlockIoPeimGetMediaInfo (
535 if (EFI_ERROR (Status
)) {
541 for (SlotNum
= 0; SlotNum
< Private
->SlotNum
; SlotNum
++) {
542 for (MediaNum
= 0; MediaNum
< Private
->Slot
[SlotNum
].MediaNum
; MediaNum
++) {
544 if (Location
== DeviceIndex
) {
554 CopyMem (MediaInfo
, &(Private
->Slot
[SlotNum
].Media
[MediaNum
]), sizeof (EFI_PEI_BLOCK_IO2_MEDIA
));
559 Reads the requested number of blocks from the specified block device.
561 The function reads the requested number of blocks from the device. All the
562 blocks are read, or an error is returned. If there is no media in the device,
563 the function returns EFI_NO_MEDIA.
565 @param[in] PeiServices General-purpose services that are available to
567 @param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO2_PPI instance.
568 @param[in] DeviceIndex Specifies the block device to which the function wants
569 to talk. Because the driver that implements Block I/O
570 PPIs will manage multiple block devices, PPIs that
571 want to talk to a single device must specify the device
572 index that was assigned during the enumeration process.
573 This index is a number from one to NumberBlockDevices.
574 @param[in] StartLBA The starting logical block address (LBA) to read from
576 @param[in] BufferSize The size of the Buffer in bytes. This number must be
577 a multiple of the intrinsic block size of the device.
578 @param[out] Buffer A pointer to the destination buffer for the data.
579 The caller is responsible for the ownership of the
582 @retval EFI_SUCCESS The data was read correctly from the device.
583 @retval EFI_DEVICE_ERROR The device reported an error while attempting
584 to perform the read operation.
585 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
586 valid, or the buffer is not properly aligned.
587 @retval EFI_NO_MEDIA There is no media in the device.
588 @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
589 the intrinsic block size of the device.
594 EmmcBlockIoPeimReadBlocks2 (
595 IN EFI_PEI_SERVICES
**PeiServices
,
596 IN EFI_PEI_RECOVERY_BLOCK_IO2_PPI
*This
,
597 IN UINTN DeviceIndex
,
598 IN EFI_PEI_LBA StartLBA
,
604 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
606 Status
= EFI_SUCCESS
;
607 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS2 (This
);
609 Status
= EmmcBlockIoPeimReadBlocks (
621 One notified function to cleanup the allocated DMA buffers at the end of PEI.
623 @param[in] PeiServices Pointer to PEI Services Table.
624 @param[in] NotifyDescriptor Pointer to the descriptor for the Notification
625 event that caused this function to execute.
626 @param[in] Ppi Pointer to the PPI data associated with this function.
628 @retval EFI_SUCCESS The function completes successfully
633 EmmcBlockIoPeimEndOfPei (
634 IN EFI_PEI_SERVICES
**PeiServices
,
635 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
639 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
641 Private
= GET_EMMC_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY (NotifyDescriptor
);
643 if ((Private
->Pool
!= NULL
) && (Private
->Pool
->Head
!= NULL
)) {
644 EmmcPeimFreeMemPool (Private
->Pool
);
651 The user code starts with this function.
653 @param FileHandle Handle of the file being invoked.
654 @param PeiServices Describes the list of possible PEI Services.
656 @retval EFI_SUCCESS The driver is successfully initialized.
657 @retval Others Can't initialize the driver.
662 InitializeEmmcBlockIoPeim (
663 IN EFI_PEI_FILE_HANDLE FileHandle
,
664 IN CONST EFI_PEI_SERVICES
**PeiServices
668 EMMC_PEIM_HC_PRIVATE_DATA
*Private
;
669 EDKII_SD_MMC_HOST_CONTROLLER_PPI
*SdMmcHcPpi
;
671 UINT32 PartitionIndex
;
678 EMMC_EXT_CSD
*ExtCsd
;
679 EMMC_HC_SLOT_CAP Capability
;
680 EMMC_PEIM_HC_SLOT
*Slot
;
685 // Shadow this PEIM to run from memory
687 if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle
))) {
692 // locate Emmc host controller PPI
694 Status
= PeiServicesLocatePpi (
695 &gEdkiiPeiSdMmcHostControllerPpiGuid
,
698 (VOID
**) &SdMmcHcPpi
700 if (EFI_ERROR (Status
)) {
701 return EFI_DEVICE_ERROR
;
709 Status
= SdMmcHcPpi
->GetSdMmcHcMmioBar (SdMmcHcPpi
, Controller
, &MmioBase
, &BarNum
);
711 // When status is error, meant no controller is found
713 if (EFI_ERROR (Status
)) {
722 Private
= AllocateCopyPool (sizeof (EMMC_PEIM_HC_PRIVATE_DATA
), &gEmmcHcPrivateTemplate
);
723 if (Private
== NULL
) {
724 Status
= EFI_OUT_OF_RESOURCES
;
727 Private
->BlkIoPpiList
.Ppi
= (VOID
*)&Private
->BlkIoPpi
;
728 Private
->BlkIo2PpiList
.Ppi
= (VOID
*)&Private
->BlkIo2Ppi
;
730 // Initialize the memory pool which will be used in all transactions.
732 Status
= EmmcPeimInitMemPool (Private
);
733 if (EFI_ERROR (Status
)) {
734 Status
= EFI_OUT_OF_RESOURCES
;
738 for (Index
= 0; Index
< BarNum
; Index
++) {
739 Status
= EmmcPeimHcGetCapability (MmioBase
[Index
], &Capability
);
740 if (EFI_ERROR (Status
)) {
743 if (Capability
.SlotType
!= 0x1) {
744 DEBUG ((DEBUG_INFO
, "The slot at 0x%x is not embedded slot type\n", MmioBase
[Index
]));
745 Status
= EFI_UNSUPPORTED
;
749 Status
= EmmcPeimHcReset (MmioBase
[Index
]);
750 if (EFI_ERROR (Status
)) {
753 Status
= EmmcPeimHcCardDetect (MmioBase
[Index
]);
754 if (EFI_ERROR (Status
)) {
757 Status
= EmmcPeimHcInitHost (MmioBase
[Index
]);
758 if (EFI_ERROR (Status
)) {
762 SlotNum
= Private
->SlotNum
;
763 Slot
= &Private
->Slot
[SlotNum
];
764 CopyMem (Slot
, &gEmmcHcSlotTemplate
, sizeof (EMMC_PEIM_HC_SLOT
));
765 Slot
->Private
= Private
;
766 Slot
->EmmcHcBase
= MmioBase
[Index
];
767 CopyMem (&Slot
->Capability
, &Capability
, sizeof (Capability
));
769 Status
= EmmcPeimIdentification (Slot
);
770 if (EFI_ERROR (Status
)) {
774 ExtCsd
= &Slot
->ExtCsd
;
775 if (ExtCsd
->ExtCsdRev
< 5) {
776 DEBUG ((DEBUG_ERROR
, "The EMMC device version is too low, we don't support!!!\n"));
777 Status
= EFI_UNSUPPORTED
;
780 if ((ExtCsd
->PartitioningSupport
& BIT0
) != BIT0
) {
781 DEBUG ((DEBUG_ERROR
, "The EMMC device doesn't support Partition Feature!!!\n"));
782 Status
= EFI_UNSUPPORTED
;
786 for (PartitionIndex
= 0; PartitionIndex
< EMMC_PEIM_MAX_PARTITIONS
; PartitionIndex
++) {
787 switch (PartitionIndex
) {
788 case EmmcPartitionUserData
:
789 SecCount
= *(UINT32
*)&ExtCsd
->SecCount
;
790 Capacity
= MultU64x32 ((UINT64
)SecCount
, 0x200);
792 case EmmcPartitionBoot1
:
793 case EmmcPartitionBoot2
:
794 Capacity
= ExtCsd
->BootSizeMult
* SIZE_128KB
;
796 case EmmcPartitionRPMB
:
797 Capacity
= ExtCsd
->RpmbSizeMult
* SIZE_128KB
;
799 case EmmcPartitionGP1
:
800 GpSizeMult
= (ExtCsd
->GpSizeMult
[0] | (ExtCsd
->GpSizeMult
[1] << 8) | (ExtCsd
->GpSizeMult
[2] << 16));
801 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
803 case EmmcPartitionGP2
:
804 GpSizeMult
= (ExtCsd
->GpSizeMult
[3] | (ExtCsd
->GpSizeMult
[4] << 8) | (ExtCsd
->GpSizeMult
[5] << 16));
805 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
807 case EmmcPartitionGP3
:
808 GpSizeMult
= (ExtCsd
->GpSizeMult
[6] | (ExtCsd
->GpSizeMult
[7] << 8) | (ExtCsd
->GpSizeMult
[8] << 16));
809 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
811 case EmmcPartitionGP4
:
812 GpSizeMult
= (ExtCsd
->GpSizeMult
[9] | (ExtCsd
->GpSizeMult
[10] << 8) | (ExtCsd
->GpSizeMult
[11] << 16));
813 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
820 MediaNum
= Slot
->MediaNum
;
822 Slot
->Media
[MediaNum
].LastBlock
= DivU64x32 (Capacity
, Slot
->Media
[MediaNum
].BlockSize
) - 1;
823 Slot
->PartitionType
[MediaNum
] = PartitionIndex
;
824 Private
->TotalBlkIoDevices
++;
832 if (!EFI_ERROR (Status
)) {
833 PeiServicesInstallPpi (&Private
->BlkIoPpiList
);
834 PeiServicesNotifyPpi (&Private
->EndOfPeiNotifyList
);
836 if (Private
->Pool
->Head
!= NULL
) {
837 EmmcPeimFreeMemPool (Private
->Pool
);