ArmPkg - Supoprt for ARM specific things that can change as the architecture changes. Plus semihosting JTAG drivers. EmbeddedPkg - Generic support for an embeddded platform. Including a light weight command line shell. BeagleBoardPkg - Platform specifics for BeagleBoard. SD Card works, but USB has issues. Looks like a bug in the open source USB stack (Our internal stack works fine). git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9518 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<BR>
 | 
						|
  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.
 | 
						|
  
 | 
						|
  All rights reserved. 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;
 | 
						|
}
 | 
						|
 
 |