> 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. 

Thanks,

Andrew Fish

> Thanks
> Feng
> 
> -----Original Message-----
> From: Haojian Zhuang [mailto:haojian.zhu...@linaro.org] 
> Sent: Thursday, July 21, 2016 10:34 AM
> To: Tian, Feng <feng.t...@intel.com>
> Cc: Leif Lindholm <leif.lindh...@linaro.org>; Ard Biesheuvel 
> <ard.biesheu...@linaro.org>; edk2-devel@lists.01.org
> Subject: [edk2] Question on eMMC and SD driver
> 
> Hi all,
> 
> I have a few questions on eMMC/SD driver when I'm working on my driver.
> 
> In my hikey platform, there's no PCI bus. So I create my own DwMmc driver to 
> do the same thing as SdMmcPciHcDxe driver. There's one controller for eMMC 
> and one controller for SD.
> 
> 1. How to support both eMMC and SD driver in the same driver? The IP is 
> designed for both eMMC/SD. If we could share the same driver, we could use 
> common code.
> I tried to follow SdMmcPciHcDxe driver. I use "Emmc(0)/Ctrl(0)" to indicate 
> the device path of eMMC controller. And I should use "Sd(0)/Ctrl(1)" to 
> indicate the device path of SD controller. Is it right?
> 
> When I tried to access one partition, I use this device path 
> "Emmc(0)/Ctrl(0)/HD(5,GPT,00354BCD-BBCB-4CB3-B5AE-CDEFCB5DAC43)". Is it right?
> 
> 
> 2. When RemainingDevicePath variable is valid, GetSlotNumber() is called in 
> both EmmcDxe and SdDxe. But how could DwMmc driver knows which stack is 
> calling it? Does it mean that I need to implement two different 
> EFI_SD_MMC_PASS_THRU_PROTOCOL interfaces? One is for eMMC, and the other one 
> is for SD.
> 
> 
> 3. How to create the connection DiskIo and eMMC?
> When RemainingDevicePath variable is valid, GetSlotNumber() is invoked in 
> EmmcDxeDriverBindingStart(). But where RemainingDevicePath is set?
> When I debug code, I got this debug message in below.
> #EmmcDxeDriverBindingStart, 909, Remain
> path:VenHw(CE660500-824D-11E0-AC72-0002A5D5C51B)
> 
> The CE660500 belongs to LcdGraphicsOutputDxe. And I didn't build it into the 
> firmware at all. I don't know where it comes from.
> If I check the eMMC device path in GetSlotNumber(), I'll skip it and DiskIo 
> won't run successfully. So partition checking won't run in DiskIo. If I force 
> the GetSlotNumber() empty to pass this RemainingDevicePath, partition 
> checking could run in DiskIo.
> I guess that something is missing between DiskIo and eMMC driver. Do you have 
> any idea on this? This issue blocks me to enable multiple slots.
> 
> 
> 4. Driver dependency. EmmcDxe and SdDxe are both UEFI_DRIVER. 
> VariableRuntimeDxe Driver is DXE_RUNTIME_DRIVER. But the dependency is in 
> below.
> 
> EmmcDxe --->  DwMmcDxe ---> BlockVariableDxe ---> VariableRuntimeDxe
> 
> Now I hack EmmcDxe from UEFI_DRIVER to DXE_RUNTIME to make this dependency 
> working. Is there any other solution without hacking?
> 
> Best Regards
> Haojian
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to