> On Jul 20, 2016, at 8:59 PM, Haojian Zhuang <[email protected]> wrote:
> 
> 
> 
> 在 07/21/2016 11:41 AM, Andrew Fish 写道:
>> 
>>> On Jul 20, 2016, at 8:23 PM, Tian, Feng <[email protected]> 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.
>> 
> 
> Yes, I have to hack it as DXE_DRIVER instead. But both EmmcDxe and PciBusDxe 
> are UEFI_DRIVER. If I submit a patch to only change EmmcDxe driver to 
> DXE_DRIVER, I doubt that it'll break other platforms.
> 
> What's the suggestion on this?
> 

The Variable stack should be a DXE_RUNTIME_DRIVER as it produces services used 
by the OS. I don't know how your driver and the OS EMMC driver can coexist. 
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf

You can use this driver, but it does not store to NVRAM just volatile memory. 
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf

Thanks,

Andrew Fish


> Best Regards
> Haojian

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to