2 The EmmcDxe driver is used to manage the EMMC device.
4 It produces BlockIo, BlockIo2 and StorageSecurity protocols to allow upper layer
5 access the EMMC device.
7 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
8 This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 // EmmcDxe Driver Binding Protocol Instance
23 EFI_DRIVER_BINDING_PROTOCOL gEmmcDxeDriverBinding
= {
24 EmmcDxeDriverBindingSupported
,
25 EmmcDxeDriverBindingStart
,
26 EmmcDxeDriverBindingStop
,
33 // Template for Emmc Partitions.
35 EMMC_PARTITION mEmmcPartitionTemplate
= {
36 EMMC_PARTITION_SIGNATURE
, // Signature
38 EmmcPartitionUnknown
, // PartitionType
42 EFI_BLOCK_IO_PROTOCOL_REVISION
,
58 FALSE
, // RemovableMedia
60 FALSE
, // LogicPartition
62 FALSE
, // WritingCache
68 EmmcSecurityProtocolIn
,
69 EmmcSecurityProtocolOut
72 EFI_ERASE_BLOCK_PROTOCOL_REVISION
,
84 Decode and print EMMC CSD Register content.
86 @param[in] Csd Pointer to EMMC_CSD data structure.
88 @retval EFI_SUCCESS The function completed successfully
95 DEBUG((DEBUG_INFO
, "== Dump Emmc Csd Register==\n"));
96 DEBUG((DEBUG_INFO
, " CSD structure 0x%x\n", Csd
->CsdStructure
));
97 DEBUG((DEBUG_INFO
, " System specification version 0x%x\n", Csd
->SpecVers
));
98 DEBUG((DEBUG_INFO
, " Data read access-time 1 0x%x\n", Csd
->Taac
));
99 DEBUG((DEBUG_INFO
, " Data read access-time 2 0x%x\n", Csd
->Nsac
));
100 DEBUG((DEBUG_INFO
, " Max. bus clock frequency 0x%x\n", Csd
->TranSpeed
));
101 DEBUG((DEBUG_INFO
, " Device command classes 0x%x\n", Csd
->Ccc
));
102 DEBUG((DEBUG_INFO
, " Max. read data block length 0x%x\n", Csd
->ReadBlLen
));
103 DEBUG((DEBUG_INFO
, " Partial blocks for read allowed 0x%x\n", Csd
->ReadBlPartial
));
104 DEBUG((DEBUG_INFO
, " Write block misalignment 0x%x\n", Csd
->WriteBlkMisalign
));
105 DEBUG((DEBUG_INFO
, " Read block misalignment 0x%x\n", Csd
->ReadBlkMisalign
));
106 DEBUG((DEBUG_INFO
, " DSR implemented 0x%x\n", Csd
->DsrImp
));
107 DEBUG((DEBUG_INFO
, " Device size 0x%x\n", Csd
->CSizeLow
| (Csd
->CSizeHigh
<< 2)));
108 DEBUG((DEBUG_INFO
, " Max. read current @ VDD min 0x%x\n", Csd
->VddRCurrMin
));
109 DEBUG((DEBUG_INFO
, " Max. read current @ VDD max 0x%x\n", Csd
->VddRCurrMax
));
110 DEBUG((DEBUG_INFO
, " Max. write current @ VDD min 0x%x\n", Csd
->VddWCurrMin
));
111 DEBUG((DEBUG_INFO
, " Max. write current @ VDD max 0x%x\n", Csd
->VddWCurrMax
));
112 DEBUG((DEBUG_INFO
, " Device size multiplier 0x%x\n", Csd
->CSizeMult
));
113 DEBUG((DEBUG_INFO
, " Erase group size 0x%x\n", Csd
->EraseGrpSize
));
114 DEBUG((DEBUG_INFO
, " Erase group size multiplier 0x%x\n", Csd
->EraseGrpMult
));
115 DEBUG((DEBUG_INFO
, " Write protect group size 0x%x\n", Csd
->WpGrpSize
));
116 DEBUG((DEBUG_INFO
, " Write protect group enable 0x%x\n", Csd
->WpGrpEnable
));
117 DEBUG((DEBUG_INFO
, " Manufacturer default ECC 0x%x\n", Csd
->DefaultEcc
));
118 DEBUG((DEBUG_INFO
, " Write speed factor 0x%x\n", Csd
->R2WFactor
));
119 DEBUG((DEBUG_INFO
, " Max. write data block length 0x%x\n", Csd
->WriteBlLen
));
120 DEBUG((DEBUG_INFO
, " Partial blocks for write allowed 0x%x\n", Csd
->WriteBlPartial
));
121 DEBUG((DEBUG_INFO
, " Content protection application 0x%x\n", Csd
->ContentProtApp
));
122 DEBUG((DEBUG_INFO
, " File format group 0x%x\n", Csd
->FileFormatGrp
));
123 DEBUG((DEBUG_INFO
, " Copy flag (OTP) 0x%x\n", Csd
->Copy
));
124 DEBUG((DEBUG_INFO
, " Permanent write protection 0x%x\n", Csd
->PermWriteProtect
));
125 DEBUG((DEBUG_INFO
, " Temporary write protection 0x%x\n", Csd
->TmpWriteProtect
));
126 DEBUG((DEBUG_INFO
, " File format 0x%x\n", Csd
->FileFormat
));
127 DEBUG((DEBUG_INFO
, " ECC code 0x%x\n", Csd
->Ecc
));
133 Decode and print EMMC EXT_CSD Register content.
135 @param[in] ExtCsd Pointer to the EMMC_EXT_CSD data structure.
137 @retval EFI_SUCCESS The function completed successfully
141 IN EMMC_EXT_CSD
*ExtCsd
144 DEBUG((DEBUG_INFO
, "==Dump Emmc ExtCsd Register==\n"));
145 DEBUG((DEBUG_INFO
, " Supported Command Sets 0x%x\n", ExtCsd
->CmdSet
));
146 DEBUG((DEBUG_INFO
, " HPI features 0x%x\n", ExtCsd
->HpiFeatures
));
147 DEBUG((DEBUG_INFO
, " Background operations support 0x%x\n", ExtCsd
->BkOpsSupport
));
148 DEBUG((DEBUG_INFO
, " Background operations status 0x%x\n", ExtCsd
->BkopsStatus
));
149 DEBUG((DEBUG_INFO
, " Number of correctly programmed sectors 0x%x\n", *((UINT32
*)&ExtCsd
->CorrectlyPrgSectorsNum
[0])));
150 DEBUG((DEBUG_INFO
, " Initialization time after partitioning 0x%x\n", ExtCsd
->IniTimeoutAp
));
151 DEBUG((DEBUG_INFO
, " TRIM Multiplier 0x%x\n", ExtCsd
->TrimMult
));
152 DEBUG((DEBUG_INFO
, " Secure Feature support 0x%x\n", ExtCsd
->SecFeatureSupport
));
153 DEBUG((DEBUG_INFO
, " Secure Erase Multiplier 0x%x\n", ExtCsd
->SecEraseMult
));
154 DEBUG((DEBUG_INFO
, " Secure TRIM Multiplier 0x%x\n", ExtCsd
->SecTrimMult
));
155 DEBUG((DEBUG_INFO
, " Boot information 0x%x\n", ExtCsd
->BootInfo
));
156 DEBUG((DEBUG_INFO
, " Boot partition size 0x%x\n", ExtCsd
->BootSizeMult
));
157 DEBUG((DEBUG_INFO
, " Access size 0x%x\n", ExtCsd
->AccSize
));
158 DEBUG((DEBUG_INFO
, " High-capacity erase unit size 0x%x\n", ExtCsd
->HcEraseGrpSize
));
159 DEBUG((DEBUG_INFO
, " High-capacity erase timeout 0x%x\n", ExtCsd
->EraseTimeoutMult
));
160 DEBUG((DEBUG_INFO
, " Reliable write sector count 0x%x\n", ExtCsd
->RelWrSecC
));
161 DEBUG((DEBUG_INFO
, " High-capacity write protect group size 0x%x\n", ExtCsd
->HcWpGrpSize
));
162 DEBUG((DEBUG_INFO
, " Sleep/awake timeout 0x%x\n", ExtCsd
->SATimeout
));
163 DEBUG((DEBUG_INFO
, " Sector Count 0x%x\n", *((UINT32
*)&ExtCsd
->SecCount
[0])));
164 DEBUG((DEBUG_INFO
, " Partition switching timing 0x%x\n", ExtCsd
->PartitionSwitchTime
));
165 DEBUG((DEBUG_INFO
, " Out-of-interrupt busy timing 0x%x\n", ExtCsd
->OutOfInterruptTime
));
166 DEBUG((DEBUG_INFO
, " I/O Driver Strength 0x%x\n", ExtCsd
->DriverStrength
));
167 DEBUG((DEBUG_INFO
, " Device type 0x%x\n", ExtCsd
->DeviceType
));
168 DEBUG((DEBUG_INFO
, " CSD STRUCTURE 0x%x\n", ExtCsd
->CsdStructure
));
169 DEBUG((DEBUG_INFO
, " Extended CSD revision 0x%x\n", ExtCsd
->ExtCsdRev
));
170 DEBUG((DEBUG_INFO
, " Command set 0x%x\n", ExtCsd
->CmdSet
));
171 DEBUG((DEBUG_INFO
, " Command set revision 0x%x\n", ExtCsd
->CmdSetRev
));
172 DEBUG((DEBUG_INFO
, " Power class 0x%x\n", ExtCsd
->PowerClass
));
173 DEBUG((DEBUG_INFO
, " High-speed interface timing 0x%x\n", ExtCsd
->HsTiming
));
174 DEBUG((DEBUG_INFO
, " Bus width mode 0x%x\n", ExtCsd
->BusWidth
));
175 DEBUG((DEBUG_INFO
, " Erased memory content 0x%x\n", ExtCsd
->ErasedMemCont
));
176 DEBUG((DEBUG_INFO
, " Partition configuration 0x%x\n", ExtCsd
->PartitionConfig
));
177 DEBUG((DEBUG_INFO
, " Boot config protection 0x%x\n", ExtCsd
->BootConfigProt
));
178 DEBUG((DEBUG_INFO
, " Boot bus Conditions 0x%x\n", ExtCsd
->BootBusConditions
));
179 DEBUG((DEBUG_INFO
, " High-density erase group definition 0x%x\n", ExtCsd
->EraseGroupDef
));
180 DEBUG((DEBUG_INFO
, " Boot write protection status register 0x%x\n", ExtCsd
->BootWpStatus
));
181 DEBUG((DEBUG_INFO
, " Boot area write protection register 0x%x\n", ExtCsd
->BootWp
));
182 DEBUG((DEBUG_INFO
, " User area write protection register 0x%x\n", ExtCsd
->UserWp
));
183 DEBUG((DEBUG_INFO
, " FW configuration 0x%x\n", ExtCsd
->FwConfig
));
184 DEBUG((DEBUG_INFO
, " RPMB Size 0x%x\n", ExtCsd
->RpmbSizeMult
));
185 DEBUG((DEBUG_INFO
, " H/W reset function 0x%x\n", ExtCsd
->RstFunction
));
186 DEBUG((DEBUG_INFO
, " Partitioning Support 0x%x\n", ExtCsd
->PartitioningSupport
));
187 DEBUG((DEBUG_INFO
, " Max Enhanced Area Size 0x%02x%02x%02x\n", \
188 ExtCsd
->MaxEnhSizeMult
[2], ExtCsd
->MaxEnhSizeMult
[1], ExtCsd
->MaxEnhSizeMult
[0]));
189 DEBUG((DEBUG_INFO
, " Partitions attribute 0x%x\n", ExtCsd
->PartitionsAttribute
));
190 DEBUG((DEBUG_INFO
, " Partitioning Setting 0x%x\n", ExtCsd
->PartitionSettingCompleted
));
191 DEBUG((DEBUG_INFO
, " General Purpose Partition 1 Size 0x%02x%02x%02x\n", \
192 ExtCsd
->GpSizeMult
[2], ExtCsd
->GpSizeMult
[1], ExtCsd
->GpSizeMult
[0]));
193 DEBUG((DEBUG_INFO
, " General Purpose Partition 2 Size 0x%02x%02x%02x\n", \
194 ExtCsd
->GpSizeMult
[5], ExtCsd
->GpSizeMult
[4], ExtCsd
->GpSizeMult
[3]));
195 DEBUG((DEBUG_INFO
, " General Purpose Partition 3 Size 0x%02x%02x%02x\n", \
196 ExtCsd
->GpSizeMult
[8], ExtCsd
->GpSizeMult
[7], ExtCsd
->GpSizeMult
[6]));
197 DEBUG((DEBUG_INFO
, " General Purpose Partition 4 Size 0x%02x%02x%02x\n", \
198 ExtCsd
->GpSizeMult
[11], ExtCsd
->GpSizeMult
[10], ExtCsd
->GpSizeMult
[9]));
199 DEBUG((DEBUG_INFO
, " Enhanced User Data Area Size 0x%02x%02x%02x\n", \
200 ExtCsd
->EnhSizeMult
[2], ExtCsd
->EnhSizeMult
[1], ExtCsd
->EnhSizeMult
[0]));
201 DEBUG((DEBUG_INFO
, " Enhanced User Data Start Address 0x%x\n", *((UINT32
*)&ExtCsd
->EnhStartAddr
[0])));
202 DEBUG((DEBUG_INFO
, " Bad Block Management mode 0x%x\n", ExtCsd
->SecBadBlkMgmnt
));
203 DEBUG((DEBUG_INFO
, " Native sector size 0x%x\n", ExtCsd
->NativeSectorSize
));
204 DEBUG((DEBUG_INFO
, " Sector size emulation 0x%x\n", ExtCsd
->UseNativeSector
));
205 DEBUG((DEBUG_INFO
, " Sector size 0x%x\n", ExtCsd
->DataSectorSize
));
211 Get EMMC device model name.
213 @param[in, out] Device The pointer to the EMMC_DEVICE data structure.
214 @param[in] Cid Pointer to EMMC_CID data structure.
216 @retval EFI_SUCCESS The function completed successfully
221 IN OUT EMMC_DEVICE
*Device
,
225 CHAR8 String
[EMMC_MODEL_NAME_MAX_LEN
];
227 ZeroMem (String
, sizeof (String
));
228 CopyMem (String
, &Cid
->OemId
, sizeof (Cid
->OemId
));
229 String
[sizeof (Cid
->OemId
)] = ' ';
230 CopyMem (String
+ sizeof (Cid
->OemId
) + 1, Cid
->ProductName
, sizeof (Cid
->ProductName
));
231 String
[sizeof (Cid
->OemId
) + sizeof (Cid
->ProductName
)] = ' ';
232 CopyMem (String
+ sizeof (Cid
->OemId
) + sizeof (Cid
->ProductName
) + 1, Cid
->ProductSerialNumber
, sizeof (Cid
->ProductSerialNumber
));
234 AsciiStrToUnicodeStrS (String
, Device
->ModelName
, sizeof (Device
->ModelName
) / sizeof (Device
->ModelName
[0]));
240 Discover all partitions in the EMMC device.
242 @param[in] Device The pointer to the EMMC_DEVICE data structure.
244 @retval EFI_SUCCESS All the partitions in the device are successfully enumerated.
245 @return Others Some error occurs when enumerating the partitions.
249 DiscoverAllPartitions (
250 IN EMMC_DEVICE
*Device
254 EMMC_PARTITION
*Partition
;
257 EMMC_EXT_CSD
*ExtCsd
;
267 Status
= EmmcSendStatus (Device
, Slot
+ 1, &DevStatus
);
268 if (EFI_ERROR (Status
)) {
272 // Deselect the device to force it enter stby mode before getting CSD
274 // Note here we don't judge return status as some EMMC devices return
275 // error but the state has been stby.
277 EmmcSelect (Device
, 0);
279 Status
= EmmcSendStatus (Device
, Slot
+ 1, &DevStatus
);
280 if (EFI_ERROR (Status
)) {
285 Status
= EmmcGetCsd (Device
, Slot
+ 1, Csd
);
286 if (EFI_ERROR (Status
)) {
291 if ((Csd
->CSizeLow
| Csd
->CSizeHigh
<< 2) == 0xFFF) {
292 Device
->SectorAddressing
= TRUE
;
294 Device
->SectorAddressing
= FALSE
;
298 Status
= EmmcGetCid (Device
, Slot
+ 1, Cid
);
299 if (EFI_ERROR (Status
)) {
303 Status
= EmmcSelect (Device
, Slot
+ 1);
304 if (EFI_ERROR (Status
)) {
308 ExtCsd
= &Device
->ExtCsd
;
309 Status
= EmmcGetExtCsd (Device
, ExtCsd
);
310 if (EFI_ERROR (Status
)) {
315 if (ExtCsd
->ExtCsdRev
< 5) {
316 DEBUG ((EFI_D_ERROR
, "The EMMC device version is too low, we don't support!!!\n"));
317 return EFI_UNSUPPORTED
;
320 if ((ExtCsd
->PartitioningSupport
& BIT0
) != BIT0
) {
321 DEBUG ((EFI_D_ERROR
, "The EMMC device doesn't support Partition Feature!!!\n"));
322 return EFI_UNSUPPORTED
;
325 for (Index
= 0; Index
< EMMC_MAX_PARTITIONS
; Index
++) {
326 Partition
= &Device
->Partition
[Index
];
327 CopyMem (Partition
, &mEmmcPartitionTemplate
, sizeof (EMMC_PARTITION
));
328 Partition
->Device
= Device
;
329 InitializeListHead (&Partition
->Queue
);
330 Partition
->BlockIo
.Media
= &Partition
->BlockMedia
;
331 Partition
->BlockIo2
.Media
= &Partition
->BlockMedia
;
332 Partition
->PartitionType
= Index
;
333 Partition
->BlockMedia
.IoAlign
= Device
->Private
->PassThru
->IoAlign
;
334 Partition
->BlockMedia
.BlockSize
= 0x200;
335 Partition
->BlockMedia
.LastBlock
= 0x00;
336 Partition
->BlockMedia
.RemovableMedia
= FALSE
;
337 Partition
->BlockMedia
.MediaPresent
= TRUE
;
338 Partition
->BlockMedia
.LogicalPartition
= FALSE
;
341 case EmmcPartitionUserData
:
342 SecCount
= *(UINT32
*)&ExtCsd
->SecCount
;
343 Capacity
= MultU64x32 ((UINT64
) SecCount
, 0x200);
345 case EmmcPartitionBoot1
:
346 case EmmcPartitionBoot2
:
347 Capacity
= ExtCsd
->BootSizeMult
* SIZE_128KB
;
349 case EmmcPartitionRPMB
:
350 Capacity
= ExtCsd
->RpmbSizeMult
* SIZE_128KB
;
352 case EmmcPartitionGP1
:
353 GpSizeMult
= (UINT32
)(ExtCsd
->GpSizeMult
[0] | (ExtCsd
->GpSizeMult
[1] << 8) | (ExtCsd
->GpSizeMult
[2] << 16));
354 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
356 case EmmcPartitionGP2
:
357 GpSizeMult
= (UINT32
)(ExtCsd
->GpSizeMult
[3] | (ExtCsd
->GpSizeMult
[4] << 8) | (ExtCsd
->GpSizeMult
[5] << 16));
358 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
360 case EmmcPartitionGP3
:
361 GpSizeMult
= (UINT32
)(ExtCsd
->GpSizeMult
[6] | (ExtCsd
->GpSizeMult
[7] << 8) | (ExtCsd
->GpSizeMult
[8] << 16));
362 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
364 case EmmcPartitionGP4
:
365 GpSizeMult
= (UINT32
)(ExtCsd
->GpSizeMult
[9] | (ExtCsd
->GpSizeMult
[10] << 8) | (ExtCsd
->GpSizeMult
[11] << 16));
366 Capacity
= MultU64x32 (MultU64x32 (MultU64x32 ((UINT64
)GpSizeMult
, ExtCsd
->HcWpGrpSize
), ExtCsd
->HcEraseGrpSize
), SIZE_512KB
);
370 return EFI_INVALID_PARAMETER
;
374 Partition
->Enable
= TRUE
;
375 Partition
->BlockMedia
.LastBlock
= DivU64x32 (Capacity
, Partition
->BlockMedia
.BlockSize
) - 1;
378 if ((ExtCsd
->EraseGroupDef
& BIT0
) == 0) {
379 if (Csd
->WriteBlLen
< 9) {
380 Partition
->EraseBlock
.EraseLengthGranularity
= 1;
382 Partition
->EraseBlock
.EraseLengthGranularity
= (Csd
->EraseGrpMult
+ 1) * (Csd
->EraseGrpSize
+ 1) * (1 << (Csd
->WriteBlLen
- 9));
385 Partition
->EraseBlock
.EraseLengthGranularity
= 1024 * ExtCsd
->HcEraseGrpSize
;
393 Install BlkIo, BlkIo2 and Ssp protocols for the specified partition in the EMMC device.
395 @param[in] Device The pointer to the EMMC_DEVICE data structure.
396 @param[in] Index The index of the partition.
398 @retval EFI_SUCCESS The protocols are installed successfully.
399 @retval Others Some error occurs when installing the protocols.
403 InstallProtocolOnPartition (
404 IN EMMC_DEVICE
*Device
,
409 EMMC_PARTITION
*Partition
;
410 CONTROLLER_DEVICE_PATH ControlNode
;
411 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
412 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
413 EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
;
414 EFI_HANDLE DeviceHandle
;
419 ParentDevicePath
= Device
->DevicePath
;
421 ControlNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
422 ControlNode
.Header
.SubType
= HW_CONTROLLER_DP
;
423 SetDevicePathNodeLength (&ControlNode
.Header
, sizeof (CONTROLLER_DEVICE_PATH
));
424 ControlNode
.ControllerNumber
= Index
;
426 DevicePath
= AppendDevicePathNode (ParentDevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&ControlNode
);
427 if (DevicePath
== NULL
) {
428 Status
= EFI_OUT_OF_RESOURCES
;
433 RemainingDevicePath
= DevicePath
;
434 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingDevicePath
, &DeviceHandle
);
435 if (!EFI_ERROR (Status
) && (DeviceHandle
!= NULL
) && IsDevicePathEnd(RemainingDevicePath
)) {
436 Status
= EFI_ALREADY_STARTED
;
440 Partition
= &Device
->Partition
[Index
];
441 Partition
->DevicePath
= DevicePath
;
442 if (Partition
->Enable
) {
444 // Install BlkIo/BlkIo2/Ssp for the specified partition
446 Status
= gBS
->InstallMultipleProtocolInterfaces (
448 &gEfiDevicePathProtocolGuid
,
449 Partition
->DevicePath
,
450 &gEfiBlockIoProtocolGuid
,
452 &gEfiBlockIo2ProtocolGuid
,
453 &Partition
->BlockIo2
,
456 if (EFI_ERROR (Status
)) {
460 if (Partition
->PartitionType
!= EmmcPartitionRPMB
) {
461 Status
= gBS
->InstallProtocolInterface (
463 &gEfiEraseBlockProtocolGuid
,
464 EFI_NATIVE_INTERFACE
,
465 &Partition
->EraseBlock
467 if (EFI_ERROR (Status
)) {
468 gBS
->UninstallMultipleProtocolInterfaces (
470 &gEfiDevicePathProtocolGuid
,
471 Partition
->DevicePath
,
472 &gEfiBlockIoProtocolGuid
,
474 &gEfiBlockIo2ProtocolGuid
,
475 &Partition
->BlockIo2
,
482 if (((Partition
->PartitionType
== EmmcPartitionUserData
) ||
483 (Partition
->PartitionType
== EmmcPartitionBoot1
) ||
484 (Partition
->PartitionType
== EmmcPartitionBoot2
)) &&
485 ((Device
->Csd
.Ccc
& BIT10
) != 0)) {
486 Status
= gBS
->InstallProtocolInterface (
488 &gEfiStorageSecurityCommandProtocolGuid
,
489 EFI_NATIVE_INTERFACE
,
490 &Partition
->StorageSecurity
492 if (EFI_ERROR (Status
)) {
493 gBS
->UninstallMultipleProtocolInterfaces (
495 &gEfiDevicePathProtocolGuid
,
496 Partition
->DevicePath
,
497 &gEfiBlockIoProtocolGuid
,
499 &gEfiBlockIo2ProtocolGuid
,
500 &Partition
->BlockIo2
,
501 &gEfiEraseBlockProtocolGuid
,
502 &Partition
->EraseBlock
,
510 Device
->Private
->Controller
,
511 &gEfiSdMmcPassThruProtocolGuid
,
512 (VOID
**) &(Device
->Private
->PassThru
),
513 Device
->Private
->DriverBindingHandle
,
515 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
518 Status
= EFI_INVALID_PARAMETER
;
522 if (EFI_ERROR (Status
) && (DevicePath
!= NULL
)) {
523 FreePool (DevicePath
);
530 Scan EMMC Bus to discover the device.
532 @param[in] Private The EMMC driver private data structure.
533 @param[in] Slot The slot number to check device present.
534 @param[in] RemainingDevicePath The pointer to the remaining device path.
536 @retval EFI_SUCCESS Successfully to discover the device and attach
537 SdMmcIoProtocol to it.
538 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
540 @retval EFI_ALREADY_STARTED The device was discovered before.
541 @retval Others Fail to discover the device.
547 IN EMMC_DRIVER_PRIVATE_DATA
*Private
,
549 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
554 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
555 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
556 EFI_DEVICE_PATH_PROTOCOL
*RemainingEmmcDevPath
;
558 EFI_HANDLE DeviceHandle
;
559 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
564 NewDevicePath
= NULL
;
565 RemainingDevicePath
= NULL
;
566 PassThru
= Private
->PassThru
;
567 Device
= &Private
->Device
[Slot
];
570 // Build Device Path to check if the EMMC device present at the slot.
572 Status
= PassThru
->BuildDevicePath (
577 if (EFI_ERROR(Status
)) {
581 if (DevicePath
->SubType
!= MSG_EMMC_DP
) {
582 Status
= EFI_UNSUPPORTED
;
586 NewDevicePath
= AppendDevicePathNode (
587 Private
->ParentDevicePath
,
590 if (NewDevicePath
== NULL
) {
591 Status
= EFI_OUT_OF_RESOURCES
;
596 RemainingEmmcDevPath
= NewDevicePath
;
597 Status
= gBS
->LocateDevicePath (&gEfiDevicePathProtocolGuid
, &RemainingEmmcDevPath
, &DeviceHandle
);
599 // The device path to the EMMC device doesn't exist. It means the corresponding device private data hasn't been initialized.
601 if (EFI_ERROR (Status
) || (DeviceHandle
== NULL
) || !IsDevicePathEnd (RemainingEmmcDevPath
)) {
602 Device
->DevicePath
= NewDevicePath
;
604 Device
->Private
= Private
;
606 // Expose user area in the Sd memory card to upper layer.
608 Status
= DiscoverAllPartitions (Device
);
609 if (EFI_ERROR(Status
)) {
610 FreePool (NewDevicePath
);
614 Status
= gBS
->InstallProtocolInterface (
616 &gEfiDevicePathProtocolGuid
,
617 EFI_NATIVE_INTERFACE
,
620 if (EFI_ERROR(Status
)) {
621 FreePool (NewDevicePath
);
625 Device
->ControllerNameTable
= NULL
;
626 GetEmmcModelName (Device
, &Device
->Cid
);
629 gEmmcDxeComponentName
.SupportedLanguages
,
630 &Device
->ControllerNameTable
,
636 gEmmcDxeComponentName
.SupportedLanguages
,
637 &Device
->ControllerNameTable
,
643 if (RemainingDevicePath
== NULL
) {
645 // Expose all partitions in the Emmc device to upper layer.
647 for (Index
= 0; Index
< EMMC_MAX_PARTITIONS
; Index
++) {
648 InstallProtocolOnPartition (Device
, Index
);
650 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
652 // Enumerate the specified partition
654 Node
= (EFI_DEV_PATH
*) RemainingDevicePath
;
655 if ((DevicePathType (&Node
->DevPath
) != HARDWARE_DEVICE_PATH
) ||
656 (DevicePathSubType (&Node
->DevPath
) != HW_CONTROLLER_DP
) ||
657 (DevicePathNodeLength (&Node
->DevPath
) != sizeof (CONTROLLER_DEVICE_PATH
))) {
658 Status
= EFI_INVALID_PARAMETER
;
662 Index
= (UINT8
)Node
->Controller
.ControllerNumber
;
663 if (Index
>= EMMC_MAX_PARTITIONS
) {
664 Status
= EFI_INVALID_PARAMETER
;
668 Status
= InstallProtocolOnPartition (Device
, Index
);
672 FreePool (DevicePath
);
678 Tests to see if this driver supports a given controller. If a child device is provided,
679 it further tests to see if this driver supports creating a handle for the specified child device.
681 This function checks to see if the driver specified by This supports the device specified by
682 ControllerHandle. Drivers will typically use the device path attached to
683 ControllerHandle and/or the services from the bus I/O abstraction attached to
684 ControllerHandle to determine if the driver supports ControllerHandle. This function
685 may be called many times during platform initialization. In order to reduce boot times, the tests
686 performed by this function must be very small, and take as little time as possible to execute. This
687 function must not change the state of any hardware devices, and this function must be aware that the
688 device specified by ControllerHandle may already be managed by the same driver or a
689 different driver. This function must match its calls to AllocatePages() with FreePages(),
690 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
691 Since ControllerHandle may have been previously started by the same driver, if a protocol is
692 already in the opened state, then it must not be closed with CloseProtocol(). This is required
693 to guarantee the state of ControllerHandle is not modified by this function.
695 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
696 @param[in] ControllerHandle The handle of the controller to test. This handle
697 must support a protocol interface that supplies
698 an I/O abstraction to the driver.
699 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
700 parameter is ignored by device drivers, and is optional for bus
701 drivers. For bus drivers, if this parameter is not NULL, then
702 the bus driver must determine if the bus controller specified
703 by ControllerHandle and the child controller specified
704 by RemainingDevicePath are both supported by this
707 @retval EFI_SUCCESS The device specified by ControllerHandle and
708 RemainingDevicePath is supported by the driver specified by This.
709 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
710 RemainingDevicePath is already being managed by the driver
712 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
713 RemainingDevicePath is already being managed by a different
714 driver or an application that requires exclusive access.
715 Currently not implemented.
716 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
717 RemainingDevicePath is not supported by the driver specified by This.
721 EmmcDxeDriverBindingSupported (
722 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
723 IN EFI_HANDLE Controller
,
724 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
728 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
729 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
733 // Test EFI_SD_MMC_PASS_THRU_PROTOCOL on the controller handle.
735 Status
= gBS
->OpenProtocol (
737 &gEfiSdMmcPassThruProtocolGuid
,
739 This
->DriverBindingHandle
,
741 EFI_OPEN_PROTOCOL_BY_DRIVER
744 if (Status
== EFI_ALREADY_STARTED
) {
748 if (EFI_ERROR (Status
)) {
753 // Test RemainingDevicePath is valid or not.
755 if ((RemainingDevicePath
!= NULL
) && !IsDevicePathEnd (RemainingDevicePath
)) {
756 Status
= PassThru
->GetSlotNumber (PassThru
, RemainingDevicePath
, &Slot
);
757 if (EFI_ERROR (Status
)) {
759 // Close the I/O Abstraction(s) used to perform the supported test
763 &gEfiSdMmcPassThruProtocolGuid
,
764 This
->DriverBindingHandle
,
772 // Close the I/O Abstraction(s) used to perform the supported test
776 &gEfiSdMmcPassThruProtocolGuid
,
777 This
->DriverBindingHandle
,
782 // Open the EFI Device Path protocol needed to perform the supported test
784 Status
= gBS
->OpenProtocol (
786 &gEfiDevicePathProtocolGuid
,
787 (VOID
**) &ParentDevicePath
,
788 This
->DriverBindingHandle
,
790 EFI_OPEN_PROTOCOL_GET_PROTOCOL
796 Starts a device controller or a bus controller.
798 The Start() function is designed to be invoked from the EFI boot service ConnectController().
799 As a result, much of the error checking on the parameters to Start() has been moved into this
800 common boot service. It is legal to call Start() from other locations,
801 but the following calling restrictions must be followed or the system behavior will not be deterministic.
802 1. ControllerHandle must be a valid EFI_HANDLE.
803 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
804 EFI_DEVICE_PATH_PROTOCOL.
805 3. Prior to calling Start(), the Supported() function for the driver specified by This must
806 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
808 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
809 @param[in] ControllerHandle The handle of the controller to start. This handle
810 must support a protocol interface that supplies
811 an I/O abstraction to the driver.
812 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
813 parameter is ignored by device drivers, and is optional for bus
814 drivers. For a bus driver, if this parameter is NULL, then handles
815 for all the children of Controller are created by this driver.
816 If this parameter is not NULL and the first Device Path Node is
817 not the End of Device Path Node, then only the handle for the
818 child device specified by the first Device Path Node of
819 RemainingDevicePath is created by this driver.
820 If the first Device Path Node of RemainingDevicePath is
821 the End of Device Path Node, no child handle is created by this
824 @retval EFI_SUCCESS The device was started.
825 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
826 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
827 @retval Others The driver failded to start the device.
832 EmmcDxeDriverBindingStart (
833 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
834 IN EFI_HANDLE Controller
,
835 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
839 EFI_SD_MMC_PASS_THRU_PROTOCOL
*PassThru
;
840 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
841 EMMC_DRIVER_PRIVATE_DATA
*Private
;
846 Status
= gBS
->OpenProtocol (
848 &gEfiSdMmcPassThruProtocolGuid
,
850 This
->DriverBindingHandle
,
852 EFI_OPEN_PROTOCOL_BY_DRIVER
854 if ((EFI_ERROR (Status
)) && (Status
!= EFI_ALREADY_STARTED
)) {
859 // Check EFI_ALREADY_STARTED to reuse the original EMMC_DRIVER_PRIVATE_DATA.
861 if (Status
!= EFI_ALREADY_STARTED
) {
862 Private
= AllocateZeroPool (sizeof (EMMC_DRIVER_PRIVATE_DATA
));
863 if (Private
== NULL
) {
864 Status
= EFI_OUT_OF_RESOURCES
;
868 Status
= gBS
->OpenProtocol (
870 &gEfiDevicePathProtocolGuid
,
871 (VOID
**) &ParentDevicePath
,
872 This
->DriverBindingHandle
,
874 EFI_OPEN_PROTOCOL_GET_PROTOCOL
876 ASSERT_EFI_ERROR (Status
);
877 Private
->PassThru
= PassThru
;
878 Private
->Controller
= Controller
;
879 Private
->ParentDevicePath
= ParentDevicePath
;
880 Private
->DriverBindingHandle
= This
->DriverBindingHandle
;
882 Status
= gBS
->InstallProtocolInterface (
885 EFI_NATIVE_INTERFACE
,
888 if (EFI_ERROR (Status
)) {
892 Status
= gBS
->OpenProtocol (
896 This
->DriverBindingHandle
,
898 EFI_OPEN_PROTOCOL_GET_PROTOCOL
900 if (EFI_ERROR (Status
)) {
905 if (RemainingDevicePath
== NULL
) {
908 Status
= PassThru
->GetNextSlot (PassThru
, &Slot
);
909 if (EFI_ERROR (Status
)) {
911 // Cannot find more legal slots.
913 Status
= EFI_SUCCESS
;
917 Status
= DiscoverEmmcDevice (Private
, Slot
, NULL
);
918 if (EFI_ERROR (Status
) && (Status
!= EFI_ALREADY_STARTED
)) {
922 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
923 Status
= PassThru
->GetSlotNumber (PassThru
, RemainingDevicePath
, &Slot
);
924 if (!EFI_ERROR (Status
)) {
925 Status
= DiscoverEmmcDevice (Private
, Slot
, NextDevicePathNode (RemainingDevicePath
));
930 if (EFI_ERROR (Status
) && (Status
!= EFI_ALREADY_STARTED
)) {
933 &gEfiSdMmcPassThruProtocolGuid
,
934 This
->DriverBindingHandle
,
938 if (Private
!= NULL
) {
939 gBS
->UninstallMultipleProtocolInterfaces (
952 Stops a device controller or a bus controller.
954 The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
955 As a result, much of the error checking on the parameters to Stop() has been moved
956 into this common boot service. It is legal to call Stop() from other locations,
957 but the following calling restrictions must be followed or the system behavior will not be deterministic.
958 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
959 same driver's Start() function.
960 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
961 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
962 Start() function, and the Start() function must have called OpenProtocol() on
963 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
965 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
966 @param[in] ControllerHandle A handle to the device being stopped. The handle must
967 support a bus specific I/O protocol for the driver
968 to use to stop the device.
969 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
970 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
971 if NumberOfChildren is 0.
973 @retval EFI_SUCCESS The device was stopped.
974 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
979 EmmcDxeDriverBindingStop (
980 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
981 IN EFI_HANDLE Controller
,
982 IN UINTN NumberOfChildren
,
983 IN EFI_HANDLE
*ChildHandleBuffer
987 BOOLEAN AllChildrenStopped
;
989 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
990 EMMC_DRIVER_PRIVATE_DATA
*Private
;
992 EMMC_PARTITION
*Partition
;
993 EFI_BLOCK_IO_PROTOCOL
*BlockIo
;
994 EFI_BLOCK_IO2_PROTOCOL
*BlockIo2
;
995 EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
*StorageSecurity
;
996 EFI_ERASE_BLOCK_PROTOCOL
*EraseBlock
;
998 LIST_ENTRY
*NextLink
;
999 EMMC_REQUEST
*Request
;
1003 if (NumberOfChildren
== 0) {
1004 Status
= gBS
->OpenProtocol (
1008 This
->DriverBindingHandle
,
1010 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1012 if (EFI_ERROR (Status
)) {
1013 return EFI_DEVICE_ERROR
;
1016 for (Index
= 0; Index
< EMMC_MAX_DEVICES
; Index
++) {
1017 Device
= &Private
->Device
[Index
];
1018 Status
= gBS
->OpenProtocol (
1020 &gEfiDevicePathProtocolGuid
,
1021 (VOID
**) &DevicePath
,
1022 This
->DriverBindingHandle
,
1024 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1026 if (EFI_ERROR (Status
)) {
1029 ASSERT (DevicePath
== Device
->DevicePath
);
1030 gBS
->UninstallProtocolInterface (
1032 &gEfiDevicePathProtocolGuid
,
1035 FreePool (Device
->DevicePath
);
1038 gBS
->UninstallProtocolInterface (
1043 gBS
->CloseProtocol (
1045 &gEfiSdMmcPassThruProtocolGuid
,
1046 This
->DriverBindingHandle
,
1054 AllChildrenStopped
= TRUE
;
1056 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1057 Status
= gBS
->OpenProtocol (
1058 ChildHandleBuffer
[Index
],
1059 &gEfiBlockIoProtocolGuid
,
1061 This
->DriverBindingHandle
,
1063 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1065 if (EFI_ERROR (Status
)) {
1066 Status
= gBS
->OpenProtocol (
1067 ChildHandleBuffer
[Index
],
1068 &gEfiBlockIo2ProtocolGuid
,
1069 (VOID
**) &BlockIo2
,
1070 This
->DriverBindingHandle
,
1072 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1074 if (EFI_ERROR (Status
)) {
1075 AllChildrenStopped
= FALSE
;
1080 if (BlockIo
!= NULL
) {
1081 Partition
= EMMC_PARTITION_DATA_FROM_BLKIO (BlockIo
);
1083 ASSERT (BlockIo2
!= NULL
);
1084 Partition
= EMMC_PARTITION_DATA_FROM_BLKIO2 (BlockIo2
);
1087 for (Link
= GetFirstNode (&Partition
->Queue
);
1088 !IsNull (&Partition
->Queue
, Link
);
1090 NextLink
= GetNextNode (&Partition
->Queue
, Link
);
1092 RemoveEntryList (Link
);
1093 Request
= EMMC_REQUEST_FROM_LINK (Link
);
1095 gBS
->CloseEvent (Request
->Event
);
1096 Request
->Token
->TransactionStatus
= EFI_ABORTED
;
1098 if (Request
->IsEnd
) {
1099 gBS
->SignalEvent (Request
->Token
->Event
);
1106 // Close the child handle
1108 Status
= gBS
->CloseProtocol (
1110 &gEfiSdMmcPassThruProtocolGuid
,
1111 This
->DriverBindingHandle
,
1112 ChildHandleBuffer
[Index
]
1115 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1116 ChildHandleBuffer
[Index
],
1117 &gEfiDevicePathProtocolGuid
,
1118 Partition
->DevicePath
,
1119 &gEfiBlockIoProtocolGuid
,
1120 &Partition
->BlockIo
,
1121 &gEfiBlockIo2ProtocolGuid
,
1122 &Partition
->BlockIo2
,
1125 if (EFI_ERROR (Status
)) {
1126 AllChildrenStopped
= FALSE
;
1129 &gEfiSdMmcPassThruProtocolGuid
,
1130 (VOID
**)&Partition
->Device
->Private
->PassThru
,
1131 This
->DriverBindingHandle
,
1132 ChildHandleBuffer
[Index
],
1133 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1139 // If Erase Block Protocol is installed, then uninstall this protocol.
1141 Status
= gBS
->OpenProtocol (
1142 ChildHandleBuffer
[Index
],
1143 &gEfiEraseBlockProtocolGuid
,
1144 (VOID
**) &EraseBlock
,
1145 This
->DriverBindingHandle
,
1147 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1150 if (!EFI_ERROR (Status
)) {
1151 Status
= gBS
->UninstallProtocolInterface (
1152 ChildHandleBuffer
[Index
],
1153 &gEfiEraseBlockProtocolGuid
,
1154 &Partition
->EraseBlock
1156 if (EFI_ERROR (Status
)) {
1159 &gEfiSdMmcPassThruProtocolGuid
,
1160 (VOID
**) &Partition
->Device
->Private
->PassThru
,
1161 This
->DriverBindingHandle
,
1162 ChildHandleBuffer
[Index
],
1163 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1165 AllChildrenStopped
= FALSE
;
1171 // If Storage Security Command Protocol is installed, then uninstall this protocol.
1173 Status
= gBS
->OpenProtocol (
1174 ChildHandleBuffer
[Index
],
1175 &gEfiStorageSecurityCommandProtocolGuid
,
1176 (VOID
**) &StorageSecurity
,
1177 This
->DriverBindingHandle
,
1179 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1182 if (!EFI_ERROR (Status
)) {
1183 Status
= gBS
->UninstallProtocolInterface (
1184 ChildHandleBuffer
[Index
],
1185 &gEfiStorageSecurityCommandProtocolGuid
,
1186 &Partition
->StorageSecurity
1188 if (EFI_ERROR (Status
)) {
1191 &gEfiSdMmcPassThruProtocolGuid
,
1192 (VOID
**) &Partition
->Device
->Private
->PassThru
,
1193 This
->DriverBindingHandle
,
1194 ChildHandleBuffer
[Index
],
1195 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1197 AllChildrenStopped
= FALSE
;
1202 FreePool (Partition
->DevicePath
);
1205 if (!AllChildrenStopped
) {
1206 return EFI_DEVICE_ERROR
;
1213 The user Entry Point for module EmmcDxe. The user code starts with this function.
1215 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1216 @param[in] SystemTable A pointer to the EFI System Table.
1218 @retval EFI_SUCCESS The entry point is executed successfully.
1219 @retval other Some errors occur when executing this entry point.
1225 IN EFI_HANDLE ImageHandle
,
1226 IN EFI_SYSTEM_TABLE
*SystemTable
1232 // Install driver model protocol(s).
1234 Status
= EfiLibInstallDriverBindingComponentName2 (
1237 &gEmmcDxeDriverBinding
,
1239 &gEmmcDxeComponentName
,
1240 &gEmmcDxeComponentName2
1242 ASSERT_EFI_ERROR (Status
);