On Mar 10, 2014, at 7:04 PM, Zeng, Star <[email protected]> wrote:

> Hi Olivier,
>  
> As we know, the BlockSize is the unit of FVB, FVB needs to depend on lower 
> protocol(SPI protocol) to do real write operation,

SPI Protocol does not seem to be part of the Open source or industry standard. 

FirmwareVolumeBlock is the last standardized/open source hop.

Thanks,

Andrew Fish

> but the unit of write operation may be one byte<image001.png>, or other 
> bytes. Anyway, we should not assume the operation unit of real flash chip. To 
> keep the atomicity, we need to be very careful.
>  
> Thanks,
> Star
> From: Tim Lewis [mailto:[email protected]] 
> Sent: Tuesday, March 11, 2014 5:42 AM
> To: [email protected]
> Subject: Re: [edk2] MdeModulePkg: (at least) 4 writes to Flash to update a NV 
> variable in UpdateVariable()
>  
> Olivier –
>  
> I don’t have the whole code section memorized, but if I remember right there 
> is the problem when there is a power failure as the variable header is being 
> written. If VAR_HEADER_VALID_ONLY was set in this case, but the entire 
> variable header was not written, wouldn’t this be another inconsistent state?
>  
> Tim
>  
> From: Olivier Martin [mailto:[email protected]] 
> Sent: Monday, March 10, 2014 12:52 PM
> To: [email protected]
> Subject: [edk2] MdeModulePkg: (at least) 4 writes to Flash to update a NV 
> variable in UpdateVariable()
>  
> Dear MdeModulePkg maintainers,
>  
> We have seen on some platforms that flash writing/erasing counts for most of 
> the boot time.
> We have also noticed UpdateVariable() (in 
> MdeModulePkg/Universal/RuntimeDxe/Variable.c) might make 4 accesses to the 
> same region of Flash to update a non-volatile variable:
>  
> // 1. Write variable header
> UpdateVariableStore (...,
>      mVariableModuleGlobal->NonVolatileLastVariableOffset,
>      sizeof (VARIABLE_HEADER),
>      (UINT8 *) NextVariable
>      );
> // 2. Set variable state to header valid
> NextVariable->State = VAR_HEADER_VALID_ONLY;
> UpdateVariableStore (...,
>        mVariableModuleGlobal->NonVolatileLastVariableOffset + OFFSET_OF 
> (VARIABLE_HEADER, State),
>        sizeof (UINT8),
>        &NextVariable->State
>        );
> // 3. Write variable data
> UpdateVariableStore (...,
>        mVariableModuleGlobal->NonVolatileLastVariableOffset + sizeof 
> (VARIABLE_HEADER),
>        (UINT32) VarSize - sizeof (VARIABLE_HEADER),
>        (UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)
>        );
> // 4. Set variable state to valid
> NextVariable->State = VAR_ADDED;
> UpdateVariableStore (...,
>        mVariableModuleGlobal->NonVolatileLastVariableOffset + OFFSET_OF 
> (VARIABLE_HEADER, State),
>        sizeof (UINT8),
>        &NextVariable->State
>        );
>  
> I understand the 4 steps are to prevent the flash to be inconsistent in case 
> of accidental reset.
> Actually the steps 1 and 2 could easily be merged (ie: do 
> 'NextVariable->State = VAR_HEADER_VALID_ONLY' in step 1).
>  
> For most variables, it is likely these 4 accesses would be into the same 
> block of flash. It means this block of flash would be written 4 times.
> Could we potentially check if we do a write to the same block of flash and do 
> a single write?
>  
> For instance (untested code):
> BlockSize = Fvb->GetBlockSize ();
> BlockStart = mVariableModuleGlobal->NonVolatileLastVariableOffset & 
> ~(BlockSize – 1);
> BlockEnd = (mVariableModuleGlobal->NonVolatileLastVariableOffset + VarSize) & 
> ~(BlockSize – 1);
> if (BlockStart == BlockEnd) {
>      NextVariable->State = VAR_ADDED;
>      UpdateVariableStore (...,
>            mVariableModuleGlobal->NonVolatileLastVariableOffset,
>            VarSize,
>            (UINT8 *) NextVariable
>            );
> } else {
>      // 1. Write variable header
>      NextVariable->State = VAR_HEADER_VALID_ONLY;
>      UpdateVariableStore (...,
>            mVariableModuleGlobal->NonVolatileLastVariableOffset,
>            sizeof (VARIABLE_HEADER),
>            (UINT8 *) NextVariable
>            );
>      // 2. Write variable data
>      UpdateVariableStore (...,
>             mVariableModuleGlobal->NonVolatileLastVariableOffset + sizeof 
> (VARIABLE_HEADER),
>             (UINT32) VarSize - sizeof (VARIABLE_HEADER),
>             (UINT8 *) NextVariable + sizeof (VARIABLE_HEADER)
>            );
>      // 3. Set variable state to valid
>      NextVariable->State = VAR_ADDED;
>      UpdateVariableStore (...,
>             mVariableModuleGlobal->NonVolatileLastVariableOffset + OFFSET_OF 
> (VARIABLE_HEADER, State),
>             sizeof (UINT8),
>             &NextVariable->State
>             );
> }
>  
> Regards,
> Olivier
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/13534_NeoTech_______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to