Пример #1
0
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
  IN NOR_FLASH_INSTANCE* Instance
  )
{
  EFI_STATUS  Status;
  UINT32      FvbNumLba;
  EFI_BOOT_MODE BootMode;

  DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));

  Instance->Initialized = TRUE;

  // Set the index of the first LBA for the FVB
  Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;

  BootMode = GetBootModeHob ();
  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
    Status = EFI_INVALID_PARAMETER;
  } else {
    // Determine if there is a valid header at the beginning of the NorFlash
    Status = ValidateFvHeader (Instance);
  }

  // Install the Default FVB header if required  
  if (EFI_ERROR(Status)) {
    // There is no valid header, so time to install one.
    DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - The FVB Header is not valid. Installing a correct one for this volume.\n"));

    // Erase all the NorFlash that is reserved for variable storage
    FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;

    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
    if (EFI_ERROR(Status)) {
      return Status;
    }

    // Install all appropriate headers
    Status = InitializeFvAndVariableStoreHeaders (Instance);
    if (EFI_ERROR(Status)) {
      return Status;
    }
  }
  return Status;
}
Пример #2
0
/**
  Main entry point.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
  @param[in] SystemTable    A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS       Successfully initialized.

**/
EFI_STATUS
EFIAPI
FvbInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                          Status;
  VOID                                *Ptr;
  VOID                                *SubPtr;
  BOOLEAN                             Initialize;
  EFI_HANDLE                          Handle;
  EFI_PHYSICAL_ADDRESS                Address;
  RETURN_STATUS                       PcdStatus;

  DEBUG ((EFI_D_INFO, "EMU Variable FVB Started\n"));

  //
  // Verify that the PCD's are set correctly.
  //
  if (
       (PcdGet32 (PcdVariableStoreSize) +
        PcdGet32 (PcdFlashNvStorageFtwWorkingSize)
       ) >
       EMU_FVB_BLOCK_SIZE
     ) {
    DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizes\n"));
    return EFI_INVALID_PARAMETER;
  }

  if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) {
    DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since "
                        "flash variables appear to be supported.\n"));
    return EFI_ABORTED;
  }

  //
  // By default we will initialize the FV contents.  But, if
  // PcdEmuVariableNvStoreReserved is non-zero, then we will
  // use this location for our buffer.
  //
  // If this location does not have a proper FV header, then
  // we will initialize it.
  //
  Initialize = TRUE;
  if (PcdGet64 (PcdEmuVariableNvStoreReserved) != 0) {
    Ptr = (VOID*)(UINTN) PcdGet64 (PcdEmuVariableNvStoreReserved);
    DEBUG ((
      EFI_D_INFO,
      "EMU Variable FVB: Using pre-reserved block at %p\n",
      Ptr
      ));
    Status = ValidateFvHeader (Ptr);
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, "EMU Variable FVB: Found valid pre-existing FV\n"));
      Initialize = FALSE;
    }
  } else {
    Ptr = AllocateAlignedRuntimePages (
            EFI_SIZE_TO_PAGES (EMU_FVB_SIZE),
            SIZE_64KB
            );
  }

  mEmuVarsFvb.BufferPtr = Ptr;

  //
  // Initialize the main FV header and variable store header
  //
  if (Initialize) {
    SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8);
    InitializeFvAndVariableStoreHeaders (Ptr);
  }
  PcdStatus = PcdSet64S (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr);
  ASSERT_RETURN_ERROR (PcdStatus);

  //
  // Initialize the Fault Tolerant Write data area
  //
  SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize));
  PcdStatus = PcdSet32S (PcdFlashNvStorageFtwWorkingBase,
                (UINT32)(UINTN) SubPtr);
  ASSERT_RETURN_ERROR (PcdStatus);

  //
  // Initialize the Fault Tolerant Write spare block
  //
  SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE);
  PcdStatus = PcdSet32S (PcdFlashNvStorageFtwSpareBase,
                (UINT32)(UINTN) SubPtr);
  ASSERT_RETURN_ERROR (PcdStatus);

  //
  // Setup FVB device path
  //
  Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Ptr;
  mEmuVarsFvb.DevicePath.MemMapDevPath.StartingAddress = Address;
  mEmuVarsFvb.DevicePath.MemMapDevPath.EndingAddress = Address + EMU_FVB_SIZE - 1;

  //
  // Install the protocols
  //
  DEBUG ((EFI_D_INFO, "Installing FVB for EMU Variable support\n"));
  Handle = 0;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiFirmwareVolumeBlock2ProtocolGuid,
                  &mEmuVarsFvb.FwVolBlockInstance,
                  &gEfiDevicePathProtocolGuid,
                  &mEmuVarsFvb.DevicePath,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for the virtual address change event
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FvbVirtualAddressChangeEvent,
                  NULL,
                  &gEfiEventVirtualAddressChangeGuid,
                  &mEmuVarsFvbAddrChangeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
Пример #3
0
EFI_STATUS
EFIAPI
NorFlashFvbInitialize (
  IN NOR_FLASH_INSTANCE* Instance
  )
{
  EFI_STATUS  Status;
  UINT32      FvbNumLba;
  EFI_BOOT_MODE BootMode;
  UINTN       RuntimeMmioRegionSize;

  DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
  ASSERT((Instance != NULL));

  //
  // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME
  //

  // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory;
  //       even if we only use the small block region at the top of the NOR Flash.
  //       The reason is when the NOR Flash memory is set into program mode, the command
  //       is written as the base of the flash region (ie: Instance->DeviceBaseAddress)
  RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size;

  Status = gDS->AddMemorySpace (
      EfiGcdMemoryTypeMemoryMappedIo,
      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME
      );
  ASSERT_EFI_ERROR (Status);

  Status = gDS->SetMemorySpaceAttributes (
      Instance->DeviceBaseAddress, RuntimeMmioRegionSize,
      EFI_MEMORY_UC | EFI_MEMORY_RUNTIME);
  ASSERT_EFI_ERROR (Status);

  mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase);

  // Set the index of the first LBA for the FVB
  Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize;

  BootMode = GetBootModeHob ();
  if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) {
    Status = EFI_INVALID_PARAMETER;
  } else {
    // Determine if there is a valid header at the beginning of the NorFlash
    Status = ValidateFvHeader (Instance);
  }

  // Install the Default FVB header if required
  if (EFI_ERROR(Status)) {
    // There is no valid header, so time to install one.
    DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__));
    DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n",
      __FUNCTION__));

    // Erase all the NorFlash that is reserved for variable storage
    FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize;

    Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR);
    if (EFI_ERROR(Status)) {
      return Status;
    }

    // Install all appropriate headers
    Status = InitializeFvAndVariableStoreHeaders (Instance);
    if (EFI_ERROR(Status)) {
      return Status;
    }
  }

  //
  // The driver implementing the variable read service can now be dispatched;
  // the varstore headers are in place.
  //
  Status = gBS->InstallProtocolInterface (
                  &gImageHandle,
                  &gEdkiiNvVarStoreFormattedGuid,
                  EFI_NATIVE_INTERFACE,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for the virtual address change event
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FvbVirtualNotifyEvent,
                  NULL,
                  &gEfiEventVirtualAddressChangeGuid,
                  &mFvbVirtualAddrChangeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}