Пример #1
0
/**
  Find Esrt Entry stored in ESRT repository. 

  @param[in]     FwClass           Firmware class guid in Esrt entry
  @param[in]     Attribute         Esrt from Non FMP or FMP instance
  @param[out]    Entry             Esrt entry returned
  
  @retval EFI_SUCCESS            Successfully find an Esrt entry
  @retval EF_NOT_FOUND           No Esrt entry found

**/
EFI_STATUS
GetEsrtEntry (
  IN  EFI_GUID              *FwClass,
  IN  UINTN                 Attribute,
  OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  UINTN                      Index;
  UINTN                      EsrtNum;

  EsrtRepository = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }
  
  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (EFI_ERROR(Status)) {
    goto EXIT;
  }

  if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
    DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
    Status = EFI_ABORTED;
    goto EXIT;
  }

  Status  = EFI_NOT_FOUND;
  EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
  for (Index = 0; Index < EsrtNum; Index++) {
    if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {
      CopyMem(Entry, &EsrtRepository[Index], sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
      Status = EFI_SUCCESS;
      break;
    }
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  return Status;
}
Пример #2
0
/**
  Do the platform specific action before the console is connected.

  Such as:
    Update console variable;
    Register new Driver#### or Boot####;
    Signal ReadyToLock event.
**/
VOID
EFIAPI
PlatformBootManagerBeforeConsole (
  VOID
  )
{
  UINTN                        Index;
  EFI_STATUS                   Status;
  WIN_NT_SYSTEM_CONFIGURATION  *Configuration;

  GetVariable2 (L"Setup", &gEfiWinNtSystemConfigGuid, (VOID **) &Configuration, NULL);
  if (Configuration != NULL) {
    //
    // SetupVariable is corrupt
    //
    Configuration->ConOutRow = PcdGet32 (PcdConOutColumn);
    Configuration->ConOutColumn = PcdGet32 (PcdConOutRow);

    Status = gRT->SetVariable (
                    L"Setup",
                    &gEfiWinNtSystemConfigGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    sizeof (WIN_NT_SYSTEM_CONFIGURATION),
                    Configuration
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status));
    }
    FreePool (Configuration);
  }

  //
  // Update the ocnsole variables.
  //
  for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {
    if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
      EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);
    }

    if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
      EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);
    }

    if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
      EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);
    }
  }

  //
  // From PI spec vol2:
  // Prior to invoking any UEFI drivers, applications, or connecting consoles, 
  // the platform should signal the event EFI_END_OF_DXE_EVENT_GUID
  //
  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
}
Пример #3
0
/**
  Load and deserialize platform configuration.

  When the function fails, output parameters are indeterminate.

  @param[out] PlatformConfig    The platform configuration to receive the
                                loaded data.

  @param[out] OptionalElements  This bitmap describes the presence of optional
                                configuration elements that have been loaded.
                                PLATFORM_CONFIG_F_DOWNGRADE means that some
                                unknown elements, present in the wire format,
                                have been ignored.

  @retval  EFI_SUCCESS         Loading & deserialization successful.
  @return                      Error codes returned by GetVariable2().
**/
EFI_STATUS
EFIAPI
PlatformConfigLoad (
  OUT PLATFORM_CONFIG *PlatformConfig,
  OUT UINT64          *OptionalElements
  )
{
  VOID       *Data;
  UINTN      DataSize;
  EFI_STATUS Status;

  //
  // Any translation done in PlatformConfigSave() would have to be mirrored
  // here. For now, just load the binary dump.
  //
  // Versioning of the binary wire format is implemented based on size
  // (only incremental changes, ie. new fields), and on GUID.
  // (Incompatible changes require a GUID change.)
  //
  Status = GetVariable2 (mVariableName, &gOvmfPlatformConfigGuid, &Data,
             &DataSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *OptionalElements = 0;
  if (DataSize > sizeof *PlatformConfig) {
    //
    // Handle firmware downgrade -- keep only leading part.
    //
    CopyMem (PlatformConfig, Data, sizeof *PlatformConfig);
    *OptionalElements |= PLATFORM_CONFIG_F_DOWNGRADE;
  } else {
    CopyMem (PlatformConfig, Data, DataSize);

    //
    // Handle firmware upgrade -- zero out missing fields.
    //
    ZeroMem ((UINT8 *)PlatformConfig + DataSize,
      sizeof *PlatformConfig - DataSize);
  }

  //
  // Based on DataSize, report the optional features that we recognize.
  //
  if (DataSize >= (OFFSET_OF (PLATFORM_CONFIG, VerticalResolution) +
                   sizeof PlatformConfig->VerticalResolution)) {
    *OptionalElements |= PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION;
  }

  FreePool (Data);
  return EFI_SUCCESS;
}
Пример #4
0
/**
  Local worker function to obtain device path information from DebugPort variable.

  Records requested settings in DebugPort device structure.

**/
EFI_DEVICE_PATH_PROTOCOL *
GetDebugPortVariable (
  VOID
  )
{
  UINTN                     DataSize;
  EFI_DEVICE_PATH_PROTOCOL  *DebugPortVariable;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  GetVariable2 (EFI_DEBUGPORT_VARIABLE_NAME, &gEfiDebugPortVariableGuid, (VOID **) &DebugPortVariable, &DataSize);
  if (DebugPortVariable == NULL) {
    return NULL;
  }

  DevicePath = DebugPortVariable;
  while (!IsDevicePathEnd (DevicePath) && !IS_UART_DEVICEPATH (DevicePath)) {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  if (IsDevicePathEnd (DevicePath)) {
    FreePool (DebugPortVariable);
    return NULL;
  } else {
    CopyMem (
      &mDebugPortDevice.BaudRate,
      &((UART_DEVICE_PATH *) DevicePath)->BaudRate,
      sizeof (((UART_DEVICE_PATH *) DevicePath)->BaudRate)
      );
    mDebugPortDevice.ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
    mDebugPortDevice.Timeout          = DEBUGPORT_UART_DEFAULT_TIMEOUT;
    CopyMem (
      &mDebugPortDevice.Parity,
      &((UART_DEVICE_PATH *) DevicePath)->Parity,
      sizeof (((UART_DEVICE_PATH *) DevicePath)->Parity)
      );
    CopyMem (
      &mDebugPortDevice.DataBits,
      &((UART_DEVICE_PATH *) DevicePath)->DataBits,
      sizeof (((UART_DEVICE_PATH *) DevicePath)->DataBits)
      );
    CopyMem (
      &mDebugPortDevice.StopBits,
      &((UART_DEVICE_PATH *) DevicePath)->StopBits,
      sizeof (((UART_DEVICE_PATH *) DevicePath)->StopBits)
      );
    return DebugPortVariable;
  }
}
Пример #5
0
/**
  Returns the value used to fill in the LastAttemptVersion field of the
  EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
  service of the Firmware Management Protocol.  The value is read from a UEFI
  variable.  If the UEFI variables does not exist, then a default last attempt
  version value is returned.

  UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"LastAttemptVersion"

  @return  The last attempt version value for the most recent capsule update.

**/
UINT32
GetLastAttemptVersionFromVariable (
  VOID
  )
{
  EFI_STATUS  Status;
  UINT32      *Value;
  UINTN       Size;
  UINT32      Version;

  Value   = NULL;
  Size    = 0;
  Version = DEFAULT_LASTATTEMPT;

  Status = GetVariable2 (VARNAME_LASTATTEMPTVERSION, &gEfiCallerIdGuid, (VOID **)&Value, &Size);
  if (EFI_ERROR (Status) || (Value == NULL)) {
    DEBUG ((DEBUG_WARN, "Warning: Failed to get the Last Attempt Version from variable.  Status = %r\n", Status));
    return Version;
  }

  //
  // No error from call
  //
  if (Size == sizeof (*Value)) {
    //
    // Successful read
    //
    Version = *Value;
  } else {
    //
    // Return default since size was unknown
    //
    DEBUG (
      (DEBUG_ERROR,
      "Getting Last Attempt Version variable returned a size different than expected. Size = 0x%x\n",
      Size)
      );
  }

  FreePool (Value);

  return Version;
}
Пример #6
0
/**
  Connect the network devices.

  @retval EFI_SUCCESS      At least one network device was connected.
  @retval EFI_DEVICE_ERROR Network devices were not connected due to an error.
**/
EFI_STATUS
ConnectNetwork (
  VOID
  )
{
  EFI_STATUS                    Status;
  BOOLEAN                       OneConnected;
  EFI_DEVICE_PATH_PROTOCOL      *Devices;
  EFI_DEVICE_PATH_PROTOCOL      *TempDevicePath;
  EFI_DEVICE_PATH_PROTOCOL      *SingleDevice;
  UINTN                         Size;

  OneConnected = FALSE;
  GetVariable2 (mNetworkDeviceList, &gEfiCallerIdGuid, (VOID **) &Devices, NULL);
  TempDevicePath = Devices;
  while (TempDevicePath != NULL) {
    SingleDevice = GetNextDevicePathInstance (&TempDevicePath, &Size);
    Status = EfiBootManagerConnectDevicePath (SingleDevice, NULL);
    if (!EFI_ERROR (Status)) {
      OneConnected = TRUE;
    }
    FreePool (SingleDevice);
  }
  if (Devices != NULL) {
    FreePool (Devices);
  }

  if (OneConnected) {
    return EFI_SUCCESS;
  } else {
    //
    // Cached network devices list doesn't exist or is NOT valid.
    //
    return ConnectAllAndCreateNetworkDeviceList ();
  }
}
Пример #7
0
/**
  Initialize CapsuleLast variables.
**/
VOID
InitCapsuleLastVariable (
  VOID
  )
{
  EFI_STATUS                       Status;
  EFI_BOOT_MODE                    BootMode;
  EDKII_VARIABLE_LOCK_PROTOCOL     *VariableLock;
  VOID                             *CapsuleResult;
  UINTN                            Size;
  CHAR16                           CapsuleLastStr[sizeof("Capsule####")];

  BootMode = GetBootModeHob();
  if (BootMode == BOOT_ON_FLASH_UPDATE) {
    Status = gRT->SetVariable(
                    L"CapsuleLast",
                    &gEfiCapsuleReportGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    0,
                    NULL
                    );
    // Do not lock it because it will be updated later.
  } else {
    //
    // Check if OS/APP cleared L"Capsule####"
    //
    ZeroMem(CapsuleLastStr, sizeof(CapsuleLastStr));
    Size = sizeof(L"Capsule####") - sizeof(CHAR16); // no zero terminator
    Status = gRT->GetVariable(
                    L"CapsuleLast",
                    &gEfiCapsuleReportGuid,
                    NULL,
                    &Size,
                    CapsuleLastStr
                    );
    if (!EFI_ERROR(Status)) {
      //
      // L"CapsuleLast" is got, check if data is there.
      //
      Status = GetVariable2 (
                 CapsuleLastStr,
                 &gEfiCapsuleReportGuid,
                 (VOID **) &CapsuleResult,
                 NULL
                 );
      if (EFI_ERROR(Status)) {
        //
        // If no data, delete L"CapsuleLast"
        //
        Status = gRT->SetVariable(
                        L"CapsuleLast",
                        &gEfiCapsuleReportGuid,
                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                        0,
                        NULL
                        );
      }
    }

    // Lock it in normal boot path per UEFI spec.
    Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
    if (!EFI_ERROR(Status)) {
      Status = VariableLock->RequestToLock(VariableLock, L"CapsuleLast", &gEfiCapsuleReportGuid);
      ASSERT_EFI_ERROR(Status);
    }
  }
}
Пример #8
0
/**
  Update the legacy BBS boot option. L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable
  is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
  is also updated.

  @param CallbackData    The context data for BMM.

  @return EFI_SUCCESS           The function completed successfully.
  @retval EFI_NOT_FOUND         If L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.
  @retval EFI_OUT_OF_RESOURCES  Fail to allocate memory resource
**/
EFI_STATUS
UpdateBBSOption (
  IN LEGACY_BOOT_NV_DATA            *NVMapData
  )
{
  UINTN                       Index;
  UINTN                       Index2;
  UINTN                       CurrentType;
  VOID                        *BootOptionVar;
  CHAR16                      VarName[100];
  UINTN                       OptionSize;
  EFI_STATUS                  Status;
  UINT32                      *Attribute;
  LEGACY_MENU_OPTION          *OptionMenu;
  UINT16                      *LegacyDev;
  UINT16                      *InitialLegacyDev;
  UINT8                       *VarData;
  UINTN                       VarSize;
  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
  UINT8                       *OriginalPtr;
  UINT8                       *DisMap;
  UINTN                       Pos;
  UINTN                       Bit;
  UINT16                      *NewOrder;
  UINT16                      Tmp;
  UINT16                      *EnBootOption;
  UINTN                       EnBootOptionCount;
  UINT16                      *DisBootOption;
  UINTN                       DisBootOptionCount;
  UINTN                       BufferSize;
  

  DisMap              = NULL;
  NewOrder            = NULL;
  CurrentType         = 0;

  
  DisMap  = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;
  Status  = EFI_SUCCESS;

  //
  // Update the Variable "LegacyDevOrder"
  //
  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &VarData, &VarSize);
  if (VarData == NULL) {
    return EFI_NOT_FOUND;
  }
  OriginalPtr = VarData;

  while (mBbsType[CurrentType] != BBS_UNKNOWN) {
    switch (mBbsType[CurrentType]) {
    case BBS_FLOPPY:
      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyFDMenu;
      LegacyDev             = NVMapData->LegacyFD;
      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;
      BufferSize            = sizeof (NVMapData->LegacyFD);
      break;

    case BBS_HARDDISK:
      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyHDMenu;
      LegacyDev             = NVMapData->LegacyHD;
      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;

      BufferSize            = sizeof (NVMapData->LegacyHD);
      break;

    case BBS_CDROM:
      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyCDMenu;
      LegacyDev             = NVMapData->LegacyCD;
      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;
      BufferSize            = sizeof (NVMapData->LegacyCD);
      break;

    case BBS_EMBED_NETWORK:
      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyNETMenu;
      LegacyDev             = NVMapData->LegacyNET;
      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;
      BufferSize            = sizeof (NVMapData->LegacyNET);
      break;

    default:
      ASSERT (mBbsType[CurrentType] == BBS_BEV_DEVICE);
      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyBEVMenu;
      LegacyDev             = NVMapData->LegacyBEV;
      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;
      BufferSize            = sizeof (NVMapData->LegacyBEV);
      break;
    }

    //
    // Check whether has value changed.
    //
    if (CompareMem (LegacyDev, InitialLegacyDev, BufferSize) == 0) {
      CurrentType++;
      continue;
    }

    DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) OriginalPtr;
    while (VarData < OriginalPtr + VarSize) {
      if (DevOrder->BbsType == mBbsType[CurrentType]) {
        break;
      }

      VarData += sizeof (BBS_TYPE) + DevOrder->Length;
      DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
    }

    if (VarData >= OriginalPtr + VarSize) {
      FreePool (OriginalPtr);
      return EFI_NOT_FOUND;
    }

    NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
    if (NewOrder == NULL) {
      FreePool (OriginalPtr);
      return EFI_OUT_OF_RESOURCES;
    }

    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
      if (0xFF == LegacyDev[Index]) {
        break;
      }

      NewOrder[Index] = LegacyDev[Index];
    }

    //
    // Only the enable/disable state of each boot device with same device type can be changed,
    // so we can count on the index information in DevOrder.
    // DisMap bit array is the only reliable source to check a device's en/dis state,
    // so we use DisMap to set en/dis state of each item in NewOrder array
    //
    for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
      Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);
      Pos = Tmp / 8;
      Bit = 7 - (Tmp % 8);
      if ((DisMap[Pos] & (1 << Bit)) != 0) {
        NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
        Index++;
      }
    }

    CopyMem (
      DevOrder->Data,
      NewOrder,
      DevOrder->Length - sizeof (DevOrder->Length)
      );
    FreePool (NewOrder);

    //
    // Update BootOrder and Boot####.Attribute
    //
    // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
    //
    ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);

    OrderLegacyBootOption4SameType (
      DevOrder->Data,
      DevOrder->Length / sizeof (UINT16) - 1,
      &EnBootOption,
      &EnBootOptionCount,
      &DisBootOption,
      &DisBootOptionCount
      );

    //
    // 2. Deactivate the DisBootOption and activate the EnBootOption
    //
    for (Index = 0; Index < DisBootOptionCount; Index++) {
      UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
      GetEfiGlobalVariable2 (VarName, (VOID **) &BootOptionVar, &OptionSize);
      if (BootOptionVar != NULL) {
        Attribute   = (UINT32 *) BootOptionVar;
        *Attribute &= ~LOAD_OPTION_ACTIVE;

        Status = gRT->SetVariable (
                        VarName,
                        &gEfiGlobalVariableGuid,
                        VAR_FLAG,
                        OptionSize,
                        BootOptionVar
                        );

        FreePool (BootOptionVar);
      }
    }

    for (Index = 0; Index < EnBootOptionCount; Index++) {
      UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
      GetEfiGlobalVariable2 (VarName, (VOID **) &BootOptionVar, &OptionSize);
      if (BootOptionVar != NULL) {
        Attribute   = (UINT32 *) BootOptionVar;
        *Attribute |= LOAD_OPTION_ACTIVE;

        Status = gRT->SetVariable (
                        VarName,
                        &gEfiGlobalVariableGuid,
                        VAR_FLAG,
                        OptionSize,
                        BootOptionVar
                        );

        FreePool (BootOptionVar);
      }
    }


    FreePool (EnBootOption);
    FreePool (DisBootOption);

    CurrentType++;
  }
  
  Status = gRT->SetVariable (
                  VAR_LEGACY_DEV_ORDER,
                  &gEfiLegacyDevOrderVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                  VarSize,
                  OriginalPtr
                  );

  FreePool (OriginalPtr);
  return Status;
}
Пример #9
0
/**

  Base on the L"LegacyDevOrder" variable to build the current order data.

**/
VOID
GetLegacyOptionsOrder (
  VOID
  )
{
  UINTN                       VarSize;
  UINT8                       *VarData;
  UINT8                       *VarTmp;
  LEGACY_DEV_ORDER_ENTRY      *DevOrder;
  UINT16                      *LegacyDev;
  UINTN                       Index;
  LEGACY_MENU_OPTION          *OptionMenu;
  UINT16                      VarDevOrder;
  UINTN                       Pos;
  UINTN                       Bit;
  UINT8                       *DisMap;

  DisMap = ZeroMem (mLegacyBootOptionPrivate->MaintainMapData->DisableMap, sizeof (mLegacyBootOptionPrivate->MaintainMapData->DisableMap));

  //
  // Get Device Order from variable
  //
  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &VarData, &VarSize);
  VarTmp = VarData;
  if (NULL != VarData) {
    DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) VarData;
    while (VarData < VarTmp + VarSize) {
      switch (DevOrder->BbsType) {
      case BBS_FLOPPY:
        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;
        OptionMenu = &LegacyFDMenu;
        break;
      
      case BBS_HARDDISK:
        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;
        OptionMenu = &LegacyHDMenu;
        break;
      
      case BBS_CDROM:
        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;
        OptionMenu = &LegacyCDMenu;
        break;
      
      case BBS_EMBED_NETWORK:
        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;
        OptionMenu = &LegacyNETMenu;
        break;
      
      case BBS_BEV_DEVICE:
        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;
        OptionMenu = &LegacyBEVMenu;
        break;
      
      case BBS_UNKNOWN:
      default:
        ASSERT (FALSE);
        DEBUG ((DEBUG_ERROR, "Unsupported device type found!\n"));
        break;
      }

      //
      // Create oneof tag here for FD/HD/CD #1 #2
      //
      for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {  
        VarDevOrder = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));
      
        if (0xFF00 == (VarDevOrder & 0xFF00)) {
          LegacyDev[Index]  = 0xFF;
          Pos               = (VarDevOrder & 0xFF) / 8;
          Bit               = 7 - ((VarDevOrder & 0xFF) % 8);
          DisMap[Pos]       = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));
        } else {
          LegacyDev[Index] = VarDevOrder & 0xFF;
        }
      }

      VarData += sizeof (BBS_TYPE);
      VarData += *(UINT16 *) VarData;
      DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
    }
  }

  CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));
  CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));
}
Пример #10
0
/**
  Build the Boot#### or Driver#### option from the VariableName.

  @param  VariableName          Variable name of the load option
  @param  VendorGuid            Variable GUID of the load option
  @param  Option                Return the load option.

  @retval EFI_SUCCESS     Get the option just been created
  @retval EFI_NOT_FOUND   Failed to get the new option

**/
EFI_STATUS
EFIAPI
EfiBootManagerVariableToLoadOptionEx (
  IN CHAR16                           *VariableName,
  IN EFI_GUID                         *VendorGuid,
  IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option  
  )
{
  EFI_STATUS                         Status;
  UINT32                             Attribute;
  UINT16                             FilePathSize;
  UINT8                              *Variable;
  UINT8                              *VariablePtr;
  UINTN                              VariableSize;
  EFI_DEVICE_PATH_PROTOCOL           *FilePath;
  UINT8                              *OptionalData;
  UINT32                             OptionalDataSize;
  CHAR16                             *Description;
  EFI_BOOT_MANAGER_LOAD_OPTION_TYPE  OptionType;
  UINT16                             OptionNumber;

  if ((VariableName == NULL) || (Option == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!BmIsValidLoadOptionVariableName (VariableName, &OptionType, &OptionNumber)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Read the variable
  //
  GetVariable2 (VariableName, VendorGuid, (VOID **) &Variable, &VariableSize);
  if (Variable == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Validate *#### variable data.
  //
  if (!BmValidateOption(Variable, VariableSize)) {
    FreePool (Variable);
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the option attribute
  //
  VariablePtr = Variable;
  Attribute = ReadUnaligned32 ((UINT32 *) VariablePtr);
  VariablePtr += sizeof (UINT32);

  //
  // Get the option's device path size
  //
  FilePathSize = ReadUnaligned16 ((UINT16 *) VariablePtr);
  VariablePtr += sizeof (UINT16);

  //
  // Get the option's description string
  //
  Description = (CHAR16 *) VariablePtr;

  //
  // Get the option's description string size
  //
  VariablePtr += StrSize ((CHAR16 *) VariablePtr);

  //
  // Get the option's device path
  //
  FilePath = (EFI_DEVICE_PATH_PROTOCOL *) VariablePtr;
  VariablePtr += FilePathSize;

  OptionalDataSize = (UINT32) (VariableSize - (UINTN) (VariablePtr - Variable));
  if (OptionalDataSize == 0) {
    OptionalData = NULL;
  } else {
    OptionalData = VariablePtr;
  }

  Status = EfiBootManagerInitializeLoadOption (
             Option,
             OptionNumber,
             OptionType,
             Attribute,
             Description,
             FilePath,
             OptionalData,
             OptionalDataSize
             );
  ASSERT_EFI_ERROR (Status);

  CopyGuid (&Option->VendorGuid, VendorGuid);

  FreePool (Variable);
  return Status;
}
Пример #11
0
/**
  Dump capsule status variable.

  @retval EFI_SUCCESS            The capsule status variable is dumped.
  @retval EFI_UNSUPPORTED        Input parameter is not valid.
**/
EFI_STATUS
DmpCapsuleStatusVariable (
  VOID
  )
{
  EFI_STATUS                          Status;
  UINT32                              Index;
  CHAR16                              CapsuleVarName[20];
  CHAR16                              *TempVarName;
  EFI_CAPSULE_RESULT_VARIABLE_HEADER  *CapsuleResult;
  EFI_CAPSULE_RESULT_VARIABLE_FMP     *CapsuleResultFmp;
  UINTN                               CapsuleFileNameSize;
  CHAR16                              CapsuleIndexData[12];
  CHAR16                              *CapsuleIndex;

  Status = GetVariable2(
             L"CapsuleMax",
             &gEfiCapsuleReportGuid,
             (VOID **)&CapsuleIndex,
             NULL
             );
  if (!EFI_ERROR(Status)) {
    CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
    CapsuleIndexData[11] = 0;
    Print(L"CapsuleMax - %s\n", CapsuleIndexData);
    FreePool(CapsuleIndex);
  }
  Status = GetVariable2(
             L"CapsuleLast",
             &gEfiCapsuleReportGuid,
             (VOID **)&CapsuleIndex,
             NULL
             );
  if (!EFI_ERROR(Status)) {
    CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));
    CapsuleIndexData[11] = 0;
    Print(L"CapsuleLast - %s\n", CapsuleIndexData);
    FreePool(CapsuleIndex);
  }


  StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");
  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
  Index = 0;

  while (TRUE) {
    UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);

    Status = GetVariable2 (
               CapsuleVarName,
               &gEfiCapsuleReportGuid,
               (VOID **) &CapsuleResult,
               NULL
               );
    if (Status == EFI_NOT_FOUND) {
      break;
    } else if (EFI_ERROR(Status)) {
      continue;
    }
    ASSERT (CapsuleResult != NULL);

    //
    // display capsule process status
    //
    if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {
      Print (L"CapsuleName: %s\n", CapsuleVarName);
      Print (L"  Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);
      Print (L"  Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);
      Print (L"  Capsule Status: %r\n", CapsuleResult->CapsuleStatus);
    }

    if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {
      if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
        CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);
        Print(L"  Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);
        Print(L"  Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);
        Print(L"  Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);
        Print(L"  Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);
        if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP)) {
          Print(L"  Capsule FMP CapsuleFileName: %s\n", (CapsuleResultFmp + 1));
          CapsuleFileNameSize = StrSize((CHAR16 *)(CapsuleResultFmp + 1));
          if (CapsuleResult->VariableTotalSize > sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + CapsuleFileNameSize) {
            Print(L"  Capsule FMP CapsuleTarget: %s\n", (UINT8 *)(CapsuleResultFmp + 1) + CapsuleFileNameSize);
          }
        }
      }
    }

    FreePool(CapsuleResult);

    Index++;
    if (Index > 0xFFFF) {
      break;
    }
  }

  return EFI_SUCCESS;
}
Пример #12
0
/**
  Dump Provisioned Capsule.

  @param[in]  DumpCapsuleInfo  The flag to indicate whether to dump the capsule inforomation.

**/
VOID
DumpProvisionedCapsule (
  IN BOOLEAN                      DumpCapsuleInfo
  )
{
  EFI_STATUS                      Status;
  CHAR16                          CapsuleVarName[30];
  CHAR16                          *TempVarName;
  UINTN                           Index;
  EFI_PHYSICAL_ADDRESS            *CapsuleDataPtr64;
  UINT16                          *BootNext;
  CHAR16                          BootOptionName[20];
  EFI_BOOT_MANAGER_LOAD_OPTION    BootNextOptionEntry;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
  EFI_SHELL_PROTOCOL              *ShellProtocol;

  Index             = 0;
  CapsuleDataPtr64  = NULL;
  BootNext          = NULL;

  ShellProtocol = GetShellProtocol ();
  if (ShellProtocol == NULL) {
    Print (L"Get Shell Protocol Fail\n");
    return ;
  }

  //
  // Dump capsule provisioned on Memory
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Memory ###\n");
  Print (L"#########################\n");
  StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME);
  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
  while (TRUE) {
    if (Index > 0) {
      UnicodeValueToStringS (
        TempVarName,
        sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
        0,
        Index,
        0
        );
    }

    Status = GetVariable2 (
              CapsuleVarName,
              &gEfiCapsuleVendorGuid,
              (VOID **) &CapsuleDataPtr64,
              NULL
              );
    if (EFI_ERROR (Status) || CapsuleDataPtr64 == NULL) {
      if (Index == 0) {
        Print (L"No data.\n");
      }
      break;
    }

    Index++;
    Print (L"Capsule Description at 0x%08x\n", *CapsuleDataPtr64);
    DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR*) (UINTN) *CapsuleDataPtr64, DumpCapsuleInfo);
  }

  //
  // Dump capsule provisioned on Disk
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Disk #####\n");
  Print (L"#########################\n");
  Status = GetVariable2 (
             L"BootNext",
             &gEfiGlobalVariableGuid,
             (VOID **) &BootNext,
             NULL
            );
  if (EFI_ERROR (Status) || BootNext == NULL) {
    Print (L"Get BootNext Variable Fail. Status = %r\n", Status);
  } else {
    UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNext);
    Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry);
    if (!EFI_ERROR (Status)) {
      //
      // Display description and device path
      //
      GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry.FilePath, &DevicePath, &Fs);
      if(!EFI_ERROR (Status)) {
        Print (L"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry.Description);
        Print (L"    %s %s\n", ShellProtocol->GetMapFromDevicePath (&DevicePath), ConvertDevicePathToText(DevicePath, TRUE, TRUE));
        DumpCapsuleFromDisk (Fs, DumpCapsuleInfo);
      }
    }
  }
}
Пример #13
0
/**
  Add new boot option for HTTP boot.

  @param[in]  Private             Pointer to the driver private data.
  @param[in]  UsingIpv6           Set to TRUE if creating boot option for IPv6.
  @param[in]  Description         The description text of the boot option.
  @param[in]  Uri                 The URI string of the boot file.
  
  @retval EFI_SUCCESS             The boot option is created successfully.
  @retval Others                  Failed to create new boot option.

**/
EFI_STATUS
HttpBootAddBootOption (
  IN   HTTP_BOOT_PRIVATE_DATA   *Private,
  IN   BOOLEAN                  UsingIpv6,
  IN   CHAR16                   *Description,
  IN   CHAR16                   *Uri
  )
{
  EFI_DEV_PATH               *Node;
  EFI_DEVICE_PATH_PROTOCOL   *TmpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL   *NewDevicePath;
  UINTN                      Length;
  CHAR8                      AsciiUri[URI_STR_MAX_SIZE];
  CHAR16                     *CurrentOrder;
  EFI_STATUS                 Status;
  UINTN                      OrderCount;
  UINTN                      TargetLocation;
  BOOLEAN                    Found;
  UINT8                      *TempByteBuffer;
  UINT8                      *TempByteStart;
  UINTN                      DescSize;
  UINTN                      FilePathSize;
  CHAR16                     OptionStr[10];
  UINT16                     *NewOrder;
  UINTN                      Index;

  NewOrder      = NULL;
  TempByteStart = NULL;
  NewDevicePath = NULL;
  NewOrder      = NULL;
  Node          = NULL;
  TmpDevicePath = NULL;
  CurrentOrder  = NULL;

  if (StrLen (Description) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Convert the scheme to all lower case.
  //
  for (Index = 0; Index < StrLen (Uri); Index++) {
    if (Uri[Index] == L':') {
      break;
    }
    if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
      Uri[Index] -= (CHAR16)(L'A' - L'a');
    }
  }

  //
  // Only accept http and https URI.
  //
  if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Create a new device path by appending the IP node and URI node to
  // the driver's parent device path
  //
  if (!UsingIpv6) {
    Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
    if (Node == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    Node->Ipv4.Header.Type    = MESSAGING_DEVICE_PATH;
    Node->Ipv4.Header.SubType = MSG_IPv4_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
  } else {
    Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
    if (Node == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    Node->Ipv6.Header.Type     = MESSAGING_DEVICE_PATH;
    Node->Ipv6.Header.SubType  = MSG_IPv6_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
  }
  TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  FreePool (Node);
  if (TmpDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Update the URI node with the input boot file URI.
  //
  UnicodeStrToAsciiStr (Uri, AsciiUri);
  Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
  Node = AllocatePool (Length);
  if (Node == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    FreePool (TmpDevicePath);
    goto ON_EXIT;
  }
  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
  Node->DevPath.SubType = MSG_URI_DP;
  SetDevicePathNodeLength (Node, Length);
  CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
  NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  FreePool (Node);
  FreePool (TmpDevicePath);
  if (NewDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Get current "BootOrder" variable and find a free target.
  //
  Length = 0;
  Status = GetVariable2 (
             L"BootOrder",
             &gEfiGlobalVariableGuid,
             (VOID **)&CurrentOrder,
             &Length 
             );
  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
    goto ON_EXIT;
  }
  OrderCount = Length / sizeof (UINT16);
  Found = FALSE;
  for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
    Found = TRUE;
    for (Index = 0; Index < OrderCount; Index++) {
      if (CurrentOrder[Index] == TargetLocation) {
        Found = FALSE;
        break;
      }
    }
    if (Found) {
      break;
    }
  }

  if (TargetLocation == 0xFFFF) {
    DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  } else {
    DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation));
  }
  
  //
  // Construct and set the "Boot####" variable
  //
  DescSize = StrSize(Description);
  FilePathSize = GetDevicePathSize (NewDevicePath);
  TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize);
  if (TempByteBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TempByteStart = TempByteBuffer;
  *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE;      // Attributes
  TempByteBuffer += sizeof (UINT32);

  *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize;    // FilePathListLength
  TempByteBuffer += sizeof (UINT16);

  CopyMem (TempByteBuffer, Description, DescSize);
  TempByteBuffer += DescSize;
  CopyMem (TempByteBuffer, NewDevicePath, FilePathSize);

  UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation);
  Status = gRT->SetVariable (
                  OptionStr,
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
                  TempByteStart
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Insert into the order list and set "BootOrder" variable
  //
  NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16));
  if (NewOrder == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16));
  NewOrder[OrderCount] = (UINT16) TargetLocation;
  Status = gRT->SetVariable (
                  L"BootOrder",
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  ((OrderCount + 1) * sizeof (UINT16)),
                  NewOrder
                  );
  

ON_EXIT:

  if (CurrentOrder != NULL) {
    FreePool (CurrentOrder);
  }
  if (NewOrder != NULL) {
    FreePool (NewOrder);
  }
  if (TempByteStart != NULL) {
    FreePool (TempByteStart);
  }
  if (NewDevicePath != NULL) {
    FreePool (NewDevicePath);
  }

  return Status;
}
Пример #14
0
/**
  Insert a new ESRT entry into ESRT Cache repository.

  @param[in]  Entry                Esrt entry to be set
  @param[in]  Attribute            Esrt from Esrt private protocol or FMP instance
  
  @retval EFI_SUCCESS          Successfully set a variable.

**/
EFI_STATUS
InsertEsrtEntry(
  IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
  UINTN                        Attribute
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepositoryNew;

  EsrtRepository    = NULL;
  EsrtRepositoryNew = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }

  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (Status == EFI_NOT_FOUND) {
    //
    // If not exist, create new Esrt cache repository
    //
    Status = gRT->SetVariable(
                    VariableName,
                    &gEfiCallerIdGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
                    Entry
                    );
    return Status;

  } else if (Status == EFI_SUCCESS) {
    //
    // if exist, update Esrt cache repository
    //
    if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
      DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
      //
      // Repository is corrupt. Clear Repository before insert new entry
      //
      Status = gRT->SetVariable(
                      VariableName,
                      &gEfiCallerIdGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      0,
                      EsrtRepository
                      );
      FreePool(EsrtRepository);
      RepositorySize = 0;
      EsrtRepository = NULL;
    }

    //
    // Check Repository size constraint
    //
    if ((Attribute == ESRT_FROM_FMP && RepositorySize >= PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY))
      ||(Attribute == ESRT_FROM_NONFMP && RepositorySize >= PcdGet32(PcdMaxNonFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) ) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    EsrtRepositoryNew = AllocatePool(RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
    if (EsrtRepositoryNew == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    if (RepositorySize != 0 && EsrtRepository != NULL) {
      CopyMem(EsrtRepositoryNew, EsrtRepository, RepositorySize);
    }
    CopyMem((UINT8 *)EsrtRepositoryNew + RepositorySize, Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));

    Status = gRT->SetVariable(
                    VariableName,
                    &gEfiCallerIdGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY),
                    EsrtRepositoryNew
                    );
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  if (EsrtRepositoryNew != NULL) {
    FreePool(EsrtRepositoryNew);
  }

  return Status;
}
Пример #15
0
/**
  Update one ESRT entry in ESRT repository

  @param[in]    Entry                Esrt entry to be set
  @param[in]    Attribute            Esrt from Non Esrt or FMP instance
  
  @retval EFI_SUCCESS          Successfully Update a variable.
  @retval EFI_NOT_FOUND        The Esrt enry doesn't exist

**/
EFI_STATUS
UpdateEsrtEntry(
  IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,
  UINTN                        Attribute
  )
{
  EFI_STATUS                 Status;
  CHAR16                     *VariableName;
  EFI_SYSTEM_RESOURCE_ENTRY  *EsrtRepository;
  UINTN                      RepositorySize;
  UINTN                      Index;
  UINTN                      EsrtNum;

  EsrtRepository    = NULL;

  //
  // Get Esrt index buffer
  //
  if (Attribute == ESRT_FROM_FMP) {
    VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
  } else {
    VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
  }

  Status = GetVariable2 (
             VariableName,
             &gEfiCallerIdGuid,
             (VOID **) &EsrtRepository,
             &RepositorySize
             );

  if (!EFI_ERROR(Status)) {
    //
    // if exist, update Esrt cache repository
    //
    if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
      DEBUG((EFI_D_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
      //
      // Repository is corrupt. Clear Repository before insert new entry
      //
      Status = gRT->SetVariable(
                      VariableName,
                      &gEfiCallerIdGuid,
                      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                      0,
                      EsrtRepository
                      );
      Status = EFI_NOT_FOUND;
      goto EXIT;
    }

    Status = EFI_NOT_FOUND;
    EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);
    for (Index = 0; Index < EsrtNum; Index++) {
      //
      // Update Esrt entry if it is found in repository
      //
      if (CompareGuid(&Entry->FwClass, &EsrtRepository[Index].FwClass)) {

        CopyMem(&EsrtRepository[Index], Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));
        //
        // Update New Repository
        //
        Status = gRT->SetVariable(
                        VariableName,
                        &gEfiCallerIdGuid,
                        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                        RepositorySize,
                        EsrtRepository
                        );
        break;
      }
    }
  }

EXIT:
  if (EsrtRepository != NULL) {
    FreePool(EsrtRepository);
  }

  return Status;
}