On Jul 20, 2016, at 8:23 PM, Tian, Feng <feng.t...@intel.com> wrote:
Hi, Haojian
If there is no PCI bus, you could implement a fake one. Just like what we did
at edk2\Omap35xxPkg\PciEmulation. Through this way, you can reuse SdMmcPciHc
driver.
For your questions:
1. The EDKII SD/MMC stack (SdMmcPciHc plus SdDxe and EmmcDxe) is used to manage all SD &
MMC host controllers & cards. Each SD & MMC host controller would be installed a
EFI_SD_MMC_PASS_THRU_PROTOCOL instance. We distinguish the card types by identification process
defined in SD & EMMC spec. after that, we will install different device paths through which
upper layer could distinguish them.
For SD host controller, the device path is Pci(x, x)\Sd(x). for EMMC host controller, the
device path is Pci(x, x)\EMMC(x)\Ctrl(x). why we appended a Ctrl(x) device node to EMMC device
path is because EMMC device has many partitions (User Data Area, BOOT1&2,
GP1&2&3&4, RPMB). We use Ctrl(x) to distinguish the partitions. But SD is different
story, it has no partitions, so we just produce Pci(x, x)\Sd(x) to distinguish different SD HCs
if they exist.
2. Just like I said above, EmmcDxe driver only runs on EMMC HCs/devices. That's
the way how SdMmcPciHc works.
3. I don't quite understand your question. The EmmcDxe driver produces BlockIo
on its partitions. Then DiskIo driver will be connected. (see UEFI spec driver
model chapter)
As for remaining device path, it must to be a EMMC device path otherwise
DriverBindingSupported() will not succeed. It means EMMC driver binding start()
would not run at all for such device path.
4. I don't know your use case. But in the first glance, it doesn't make sense.
How could you SD driver depends on a variable service? Could you clarify more?
I would also point out that a UEFI_DRIVER by definition will only be loaded
when all the EFI services are available. So no Depex does not mean run right
away it means you depend on all the architectural protocols
This is the list of architectural protocols:
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c#L27
EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols[] = {
{ &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL,
NULL, FALSE },
{ &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL,
NULL, FALSE },
{ &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL,
NULL, FALSE },
{ &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL,
NULL, FALSE },
{ &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL,
NULL, FALSE },
{ &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL,
NULL, FALSE },
{ &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL,
NULL, FALSE },
{ &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL,
NULL, FALSE },
{ NULL, (VOID **)NULL, NULL,
NULL, FALSE }
};
This is the code that handles the NO Depex case.
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c#L236
if (DriverEntry->Depex == NULL) {
//
// A NULL Depex means treat the driver like an UEFI 2.0 thing.
//
Status = CoreAllEfiServicesAvailable ();
DEBUG ((DEBUG_DISPATCH, " All UEFI Services Available =
"));
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_DISPATCH, "FALSE\n RESULT = FALSE\n"));
return FALSE;
}
DEBUG ((DEBUG_DISPATCH, "TRUE\n RESULT = TRUE\n"));
return TRUE;
}
Trying to store the EFI Variables on the EMMC card is probably not going to
really work.