Trailing spaces create issue/warning when generating/applying patches. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ronald Cron <ronald.cron@arm.com> Reviewed-By: Olivier Martin <olivier.martin@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15833 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			307 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Variable services implemented from system memory
 | |
| 
 | |
|   There is just a single runtime memory buffer that contans all the data.
 | |
| 
 | |
|   Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
 | |
|   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
 | |
| 
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| 
 | |
| **/
 | |
| 
 | |
| 
 | |
| UINT64    mMaximumVariableStorageSize;
 | |
| UINT64    mRemainingVariableStorageSize;
 | |
| UINT64    mMaximumVariableSize;
 | |
| 
 | |
| typedef struct {
 | |
|   EFI_GUID        VendorGuid;
 | |
|   UINT32          Attribute;
 | |
|   UINTN           DataSize;
 | |
| } VARIABLE_ARRAY_ENTRY;
 | |
| // CHAR16         VariableName[]
 | |
| // UINT8          Data[]
 | |
| 
 | |
| VARIABLE_ARRAY_ENTRY  *mVariableArray         = NULL;
 | |
| VARIABLE_ARRAY_ENTRY  *mVariableArrayNextFree = NULL;
 | |
| VARIABLE_ARRAY_ENTRY  *mVariableArrayEnd      = NULL;
 | |
| 
 | |
| 
 | |
| VARIABLE_ARRAY_ENTRY  *
 | |
| AddEntry (
 | |
|   IN CHAR16        *VariableName,
 | |
|   IN EFI_GUID      *VendorGuid,
 | |
|   IN UINT32        Attributes,
 | |
|   IN UINTN         DataSize,
 | |
|   IN VOID          *Data
 | |
|   )
 | |
| {
 | |
|   UINTN                   Size;
 | |
|   UINTN                   SizeOfString;
 | |
|   VARIABLE_ARRAY_ENTRY    *Entry;
 | |
|   EFI_TPL                 CurrentTpl;
 | |
| 
 | |
| 
 | |
|   SizeOfString = StrSize (VariableName);
 | |
|   Size = SizeOfString + sizeof (VARIABLE_ARRAY_ENTRY) + DataSize;
 | |
|   if ((VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + Size) > mVariableArrayEnd) {
 | |
|     // ran out of space
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   if (!EfiAtRuntime ()) {
 | |
|     // Enter critical section
 | |
|     CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
 | |
|   }
 | |
| 
 | |
|   Entry = mVariableArrayNextFree;
 | |
|   CopyGuid (&Entry->VendorGuid, VendorGuid);
 | |
|   Entry->Attribute = Attributes;
 | |
|   Entry->DataSize = DataSize;
 | |
|   StrCpy ((CHAR16 *)++mVariableArrayNextFree, VariableName);
 | |
|   mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + SizeOfString);
 | |
|   CopyMem (mVariableArrayNextFree, Data, DataSize);
 | |
|   mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) + DataSize);
 | |
| 
 | |
|   if (!EfiAtRuntime ()) {
 | |
|     // Exit Critical section
 | |
|     gBS->RestoreTPL (CurrentTpl);
 | |
|   }
 | |
| 
 | |
|   return Entry;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| DeleteEntry (
 | |
|   IN  VARIABLE_ARRAY_ENTRY *Entry
 | |
|   )
 | |
| {
 | |
|   UINTN       Size;
 | |
|   UINT8       *Data;
 | |
|   EFI_TPL     CurrentTpl;
 | |
| 
 | |
|   Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;
 | |
|   Data = ((UINT8 *)Entry) + Size;
 | |
| 
 | |
|   CopyMem (Entry, Data, (UINTN)mVariableArrayNextFree - (UINTN)Data);
 | |
| 
 | |
|   if (!EfiAtRuntime ()) {
 | |
|     // Enter critical section
 | |
|     CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);
 | |
|   }
 | |
| 
 | |
|   mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArrayNextFree) - Size);
 | |
| 
 | |
|   if (!EfiAtRuntime ()) {
 | |
|     // Exit Critical section
 | |
|     gBS->RestoreTPL (CurrentTpl);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| VARIABLE_ARRAY_ENTRY *
 | |
| GetVariableArrayEntry (
 | |
|   IN CHAR16        *VariableName,
 | |
|   IN EFI_GUID      *VendorGuid,
 | |
|   OUT VOID         **Data          OPTIONAL
 | |
|   )
 | |
| {
 | |
|   VARIABLE_ARRAY_ENTRY    *Entry;
 | |
|   UINTN                   Size;
 | |
| 
 | |
|   if (*VariableName == L'\0') {
 | |
|     // by definition first entry is null-terminated string
 | |
|     if (mVariableArray == mVariableArrayNextFree) {
 | |
|       return NULL;
 | |
|     }
 | |
|     return mVariableArray;
 | |
|   }
 | |
| 
 | |
|   for (Entry = mVariableArray; Entry < mVariableArrayEnd;) {
 | |
|     if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {
 | |
|       if (StrCmp (VariableName, (CHAR16 *)(Entry + 1))) {
 | |
|         Size = StrSize ((CHAR16 *)(Entry + 1));
 | |
|         if (Data != NULL) {
 | |
|           *Data = (VOID *)(((UINT8 *)Entry) + (Size + sizeof (VARIABLE_ARRAY_ENTRY)));
 | |
|         }
 | |
|         return Entry;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     Size = StrSize ((CHAR16 *)(Entry + 1)) + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize;
 | |
|     Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + Size);
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| LibGetVariable (
 | |
|   IN CHAR16        *VariableName,
 | |
|   IN EFI_GUID      *VendorGuid,
 | |
|   OUT UINT32       *Attributes OPTIONAL,
 | |
|   IN OUT UINTN     *DataSize,
 | |
|   OUT VOID         *Data
 | |
|   )
 | |
| {
 | |
|   VARIABLE_ARRAY_ENTRY    *Entry;
 | |
|   VOID                    *InternalData;
 | |
| 
 | |
|   if (EfiAtRuntime () && (Attributes != NULL)) {
 | |
|     if ((*Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);
 | |
|   if (Entry == NULL) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   if (*DataSize < Entry->DataSize) {
 | |
|     *DataSize = Entry->DataSize;
 | |
|     return EFI_BUFFER_TOO_SMALL;
 | |
|   }
 | |
| 
 | |
|   *DataSize = Entry->DataSize;
 | |
|   if (Attributes != NULL) {
 | |
|     *Attributes = Entry->Attribute;
 | |
|   }
 | |
| 
 | |
|   CopyMem (Data, InternalData, *DataSize);
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| LibGetNextVariableName (
 | |
|   IN OUT UINTN     *VariableNameSize,
 | |
|   IN OUT CHAR16    *VariableName,
 | |
|   IN OUT EFI_GUID  *VendorGuid
 | |
|   )
 | |
| {
 | |
|   VARIABLE_ARRAY_ENTRY    *Entry;
 | |
|   VOID                    *InternalData;
 | |
|   UINTN                   StringSize;
 | |
|   BOOLEAN                 Done;
 | |
| 
 | |
|   for (Done = FALSE; !Done; ) {
 | |
|     Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);
 | |
|     if (Entry == NULL) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     // If we are at runtime skip variables that do not have the Runitme attribute set.
 | |
|     Done = (EfiAtRuntime () && ((Entry->Attribute & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) ? FALSE : TRUE;
 | |
|   }
 | |
| 
 | |
|   StringSize = StrSize ((CHAR16 *)(Entry + 1));
 | |
|   Entry = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)Entry) + (StringSize + sizeof (VARIABLE_ARRAY_ENTRY) + Entry->DataSize));
 | |
|   if (Entry >= mVariableArrayEnd) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   if (*VariableNameSize < StringSize) {
 | |
|     *VariableNameSize = StringSize;
 | |
|     return EFI_BUFFER_TOO_SMALL;
 | |
|   }
 | |
| 
 | |
|   *VariableNameSize = StringSize;
 | |
|   CopyMem (VariableName, (CHAR16 *)(Entry + 1), StringSize);
 | |
|   CopyMem (VendorGuid, &Entry->VendorGuid, sizeof (EFI_GUID));
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| LibSetVariable (
 | |
|   IN CHAR16        *VariableName,
 | |
|   IN EFI_GUID      *VendorGuid,
 | |
|   IN UINT32        Attributes,
 | |
|   IN UINTN         DataSize,
 | |
|   IN VOID          *Data
 | |
|   )
 | |
| {
 | |
|   VARIABLE_ARRAY_ENTRY    *Entry;
 | |
|   VOID                    *InternalData;
 | |
| 
 | |
|   if (EfiAtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   Entry = GetVariableArrayEntry (VariableName, VendorGuid, &InternalData);
 | |
|   if (Entry == NULL) {
 | |
|     if (DataSize == 0) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
|     Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);
 | |
|     return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;
 | |
| 
 | |
|   } else if (DataSize == 0) {
 | |
|     // DataSize is zero so delete
 | |
|     DeleteEntry (Entry);
 | |
|   } else if (DataSize == Entry->DataSize) {
 | |
|     // No change is size so just update the store
 | |
|     Entry->Attribute |= Attributes;
 | |
|     CopyMem (InternalData, Data, DataSize);
 | |
|   } else {
 | |
|     // Grow the entry by deleting and adding back. Don't lose previous Attributes
 | |
|     Attributes |= Entry->Attribute;
 | |
|     DeleteEntry (Entry);
 | |
|     Entry = AddEntry (VariableName, VendorGuid, Attributes, DataSize, Data);
 | |
|     return (Entry == NULL) ? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| EFI_STATUS
 | |
| LibQueryVariableInfo (
 | |
|   IN  UINT32                 Attributes,
 | |
|   OUT UINT64                 *MaximumVariableStorageSize,
 | |
|   OUT UINT64                 *RemainingVariableStorageSize,
 | |
|   OUT UINT64                 *MaximumVariableSize
 | |
|   )
 | |
| {
 | |
|   *MaximumVariableStorageSize   = mMaximumVariableStorageSize;
 | |
|   *RemainingVariableStorageSize = mRemainingVariableStorageSize;
 | |
|   *MaximumVariableStorageSize   = mRemainingVariableStorageSize;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| VOID
 | |
| LibVariableVirtualAddressChangeEvent (VOID)
 | |
| {
 | |
|   EfiConvertPointer (0, (VOID **)&mVariableArray);
 | |
|   EfiConvertPointer (0, (VOID **)&mVariableArrayNextFree);
 | |
|   EfiConvertPointer (0, (VOID **)&mVariableArrayEnd);
 | |
| }
 | |
| 
 | |
| 
 | |
| VOID
 | |
| LibVariableInitialize (VOID)
 | |
| {
 | |
|   UINTN     Size;
 | |
| 
 | |
|   Size = PcdGet32 (PcdEmbeddedMemVariableStoreSize);
 | |
|   mVariableArray = mVariableArrayNextFree = (VARIABLE_ARRAY_ENTRY *)AllocateRuntimePool (Size);
 | |
|   ASSERT (mVariableArray != NULL);
 | |
| 
 | |
|   mVariableArrayEnd = (VARIABLE_ARRAY_ENTRY *)(((UINT8 *)mVariableArray) + Size);
 | |
| 
 | |
|   mMaximumVariableStorageSize   = Size - sizeof (VARIABLE_ARRAY_ENTRY);
 | |
|   mRemainingVariableStorageSize = mMaximumVariableStorageSize;
 | |
|   mMaximumVariableSize          = mMaximumVariableStorageSize;
 | |
| }
 | |
| 
 |