Esempio n. 1
0
/**
 * The following function presumes that the block has already been unlocked.
 **/
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock (
    IN NOR_FLASH_INSTANCE     *Instance,
    IN UINTN                  BlockAddress
)
{
    EFI_STATUS      Status;
    UINTN           Index;
    EFI_TPL         OriginalTPL;

    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);

    Index = 0;
    // The block erase might fail a first time (SW bug ?). Retry it ...
    do {
        // Unlock the block if we have to
        Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
        if (!EFI_ERROR(Status)) {
            Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
        }
        Index++;
    } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));

    if (Index == NOR_FLASH_ERASE_RETRY) {
        DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));
    }

    // Interruptions can resume.
    gBS->RestoreTPL (OriginalTPL);

    return Status;
}
Esempio n. 2
0
/**
 * This function unlock and erase an entire NOR Flash block.
 **/
EFI_STATUS
NorFlashUnlockAndEraseSingleBlock (
  IN NOR_FLASH_INSTANCE     *Instance,
  IN UINTN                  BlockAddress
  )
{
  EFI_STATUS      Status;
  UINTN           Index;
  EFI_TPL         OriginalTPL;

  if (!EfiAtRuntime ()) {
    // Raise TPL to TPL_HIGH to stop anyone from interrupting us.
    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
  } else {
    // This initialization is only to prevent the compiler to complain about the
    // use of uninitialized variables
    OriginalTPL = TPL_HIGH_LEVEL;
  }

  Index = 0;
  // The block erase might fail a first time (SW bug ?). Retry it ...
  do {
    // Unlock the block if we have to
    Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
    if (EFI_ERROR (Status)) {
      break;
    }
    Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
    Index++;
  } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));

  if (Index == NOR_FLASH_ERASE_RETRY) {
    DEBUG((EFI_D_ERROR,"EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error (try to erase %d times)\n", BlockAddress,Index));
  }

  if (!EfiAtRuntime ()) {
    // Interruptions can resume.
    gBS->RestoreTPL (OriginalTPL);
  }

  return Status;
}