variable.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 667 行 · 第 1/2 页

C
667
字号
/*++

Copyright (c) 2004, Intel Corporation                                                         
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.             

Module Name:

  Variable.c

Abstract:

  Framework PEIM to provide the Variable functionality

--*/

#include "Tiano.h"
#include "Pei.h"
#include "PeiLib.h"
#include "Variable.h"
#include "EfiHobLib.h"

//
// Module globals
//
static PEI_READ_ONLY_VARIABLE_PPI mVariablePpi = {
  PeiGetVariable,
  PeiGetNextVariableName
};

static EFI_PEI_PPI_DESCRIPTOR     mPpiListVariable = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gPeiReadOnlyVariablePpiGuid,
  &mVariablePpi
};

EFI_GUID                          gEfiVariableIndexTableGuid = EFI_VARIABLE_INDEX_TABLE_GUID;

EFI_PEIM_ENTRY_POINT (PeimInitializeVariableServices)

EFI_STATUS
EFIAPI
PeimInitializeVariableServices (
  IN EFI_FFS_FILE_HEADER       *FfsHeader,
  IN EFI_PEI_SERVICES          **PeiServices
  )
/*++

Routine Description:

  Provide the functionality of the variable services.

Arguments:
  
  FfsHeadher  - The FFS file header
  PeiServices - General purpose services available to every PEIM.

Returns:

  Status -  EFI_SUCCESS if the interface could be successfully
            installed

--*/
{
  //
  // Publish the variable capability to other modules
  //
  return (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable);

}

INTN
StrCmp (
  IN CHAR16   *s1,
  IN CHAR16   *s2
  )
/*++

Routine Description:

  This function compares two strings

Arguments:
  s1 - The first string for comparison
  s2 - The second string for comparison

Returns:
   
  0 - Two strings are the same
  Others - Two strings are not the same

--*/
{
  while (*s1) {
    if (*s1 != *s2) {
      break;
    }

    s1 += 1;
    s2 += 1;
  }

  return *s1 -*s2;
}

VARIABLE_HEADER *
GetNextVariablePtr (
  IN VARIABLE_HEADER  *Variable
  )
/*++

Routine Description:

  This code checks if variable header is valid or not.

Arguments:
  Variable       Pointer to the Variable Header.

Returns:
  TRUE            Variable header is valid.
  FALSE           Variable header is not valid.

--*/
{
  return (VARIABLE_HEADER *) ((UINTN) GET_VARIABLE_DATA_PTR (Variable) + Variable->DataSize + GET_PAD_SIZE (Variable->DataSize));
}

BOOLEAN
EFIAPI
IsValidVariableHeader (
  IN  VARIABLE_HEADER   *Variable
  )
/*++

Routine Description:

  This code checks if variable header is valid or not.

Arguments:
  Variable              Pointer to the Variable Header.

Returns:
  TRUE            Variable header is valid.
  FALSE           Variable header is not valid.

--*/
{
  if (Variable == NULL ||
      Variable->StartId != VARIABLE_DATA ||
      (sizeof (VARIABLE_HEADER) + Variable->DataSize + Variable->NameSize) > MAX_VARIABLE_SIZE
      ) {
    return FALSE;
  }

  return TRUE;
}

VARIABLE_STORE_STATUS
EFIAPI
GetVariableStoreStatus (
  IN VARIABLE_STORE_HEADER *VarStoreHeader
  )
/*++

Routine Description:

  This code gets the pointer to the variable name.

Arguments:

  VarStoreHeader  Pointer to the Variable Store Header.

Returns:

  EfiRaw        Variable store is raw
  EfiValid      Variable store is valid
  EfiInvalid    Variable store is invalid

--*/
{
  if (VarStoreHeader->Signature == VARIABLE_STORE_SIGNATURE &&
      VarStoreHeader->Format == VARIABLE_STORE_FORMATTED &&
      VarStoreHeader->State == VARIABLE_STORE_HEALTHY
      ) {

    return EfiValid;
  }

  if (VarStoreHeader->Signature == 0xffffffff &&
      VarStoreHeader->Size == 0xffffffff &&
      VarStoreHeader->Format == 0xff &&
      VarStoreHeader->State == 0xff
      ) {

    return EfiRaw;
  } else {
    return EfiInvalid;
  }
}

EFI_STATUS
GetFirstGuidHob (
  IN     VOID      **HobStart,
  IN     EFI_GUID  * Guid,
  OUT    VOID      **Buffer,
  OUT    UINTN     *BufferSize OPTIONAL
  )
/*++

Routine Description:

  This code get the first GUID Hob.

Arguments:

  HobStart    - A pointer to the start of the hobs.
  Guid        - A pointer to the EFI_GUID structure.
  Buffer      - A pointer to the buffer.
  BufferSize  - A pointer to the Buffer's size.

Returns:

  EFI_SUCCESS    - Get it successfully
  EFI_NOT_FOUND  - Fail to find it
 
--*/
{
  EFI_STATUS            Status;
  EFI_PEI_HOB_POINTERS  GuidHob;

  GuidHob.Raw = *HobStart;

  for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {

    if (END_OF_HOB_LIST (GuidHob)) {
      return EFI_NOT_FOUND;
    }

    if (GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
      if (((INT32 *) Guid)[0] == ((INT32 *) &GuidHob.Guid->Name)[0] &&
          ((INT32 *) Guid)[1] == ((INT32 *) &GuidHob.Guid->Name)[1] &&
          ((INT32 *) Guid)[2] == ((INT32 *) &GuidHob.Guid->Name)[2] &&
          ((INT32 *) Guid)[3] == ((INT32 *) &GuidHob.Guid->Name)[3]
          ) {
        Status  = EFI_SUCCESS;
        *Buffer = (VOID *) ((UINT8 *) (&GuidHob.Guid->Name) + sizeof (EFI_GUID));
        if (BufferSize != NULL) {
          *BufferSize = GuidHob.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE);
        }
      }
    }

    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
  }

  return Status;
}

EFI_STATUS
CompareWithValidVariable (
  IN  VARIABLE_HEADER         *Variable,
  IN  CHAR16                  *VariableName,
  IN  EFI_GUID                *VendorGuid,
  OUT VARIABLE_POINTER_TRACK  *PtrTrack
  )
/*++

Routine Description:

  This function compares a variable with variable entries in database

Arguments:

  Variable       - Pointer to the variable in our database
  VariableName   - Name of the variable to compare to 'Variable'
  VendorGuid     - GUID of the variable to compare to 'Variable'
  PtrTrack       - Variable Track Pointer structure that contains
                   Variable Information.

Returns:

  EFI_SUCCESS    - Found match variable
  EFI_NOT_FOUND  - Variable not found
 
--*/
{
  if (VariableName[0] == 0) {
    PtrTrack->CurrPtr = Variable;
    return EFI_SUCCESS;
  } else {
    //
    // Don't use CompareGuid function here for performance reasons.
    // Instead we compare the GUID a UINT32 at a time and branch
    // on the first failed comparison.
    //
    if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) &&
        (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) &&
        (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) &&
        (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3])
        ) {
      if (!StrCmp (VariableName, GET_VARIABLE_NAME_PTR (Variable))) {
        PtrTrack->CurrPtr = Variable;
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_NOT_FOUND;
}

EFI_STATUS
EFIAPI
FindVariable (
  IN EFI_PEI_SERVICES         **PeiServices,
  IN  CHAR16                  *VariableName,
  IN  EFI_GUID                *VendorGuid,
  OUT VARIABLE_POINTER_TRACK  *PtrTrack
  )
/*++

Routine Description:

  This code finds variable in storage blocks (Non-Volatile)

Arguments:

  PeiServices    - General purpose services available to every PEIM.
  VariableName   - Name of the variable to be found
  VendorGuid     - Vendor GUID to be found.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?