IMHO, looks there is no pure s/w way to implement saving variable to EMMC card 
with current UEFI interface.

Just like Andrew said, the variable service belongs to Arch protocol. If you 
want to save variable to EMMC card, it means you have to implement EMMC device 
driver as a DXE Runtime driver and run it at early phase. But the question is 
how do you handle the conflict of OS EMMC driver and the BIOS EMMC driver when 
somebody invokes variable service at OS but OS is accessing the same block 
through OS EMMC driver?

Correct me if anybody has different opinion.

Thanks
Feng

-----Original Message-----
From: [email protected] [mailto:[email protected]] 
Sent: Thursday, July 21, 2016 12:04 PM
To: Haojian Zhuang <[email protected]>
Cc: Tian, Feng <[email protected]>; [email protected]; Leif Lindholm 
<[email protected]>; Ard Biesheuvel <[email protected]>
Subject: Re: [edk2] Question on eMMC and SD driver


> 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/D
>> xeMain/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/D
>> ispatcher/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