/*++

Copyright (c) 2006, 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:

    Fvb.c 

Abstract:

  Firmware Volume Block Protocol Runtime Abstraction

  mFvbEntry is an array of Handle Fvb pairs. The Fvb Lib Instance matches the 
  index in the mFvbEntry array. This should be the same sequence as the FVB's
  were described in the HOB. We have to remember the handle so we can tell if 
  the protocol has been reinstalled and it needs updateing.

  If you are using any of these lib functions.you must first call FvbInitialize ().

Key:
  FVB - Firmware Volume Block

--*/

#include "Fvb.h"

//
// Lib will ASSERT if more FVB devices than this are added to the system.
//
STATIC FVB_ENTRY          *mFvbEntry;
STATIC EFI_EVENT          mFvbVirtualNotifyEvent;
STATIC EFI_EVENT          mFvbRegistration;
STATIC EFI_EVENT          mEfiFvbVirtualNotifyEvent;
STATIC BOOLEAN            mEfiFvbInitialized        = FALSE;
STATIC UINTN              mFvbCount;

STATIC
VOID
EFIAPI
FvbNotificationEvent (
  IN  EFI_EVENT       Event,
  IN  VOID            *Context
  )
/*++

Routine Description:
  Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
  reinstalled.

Arguments:

  Event   - The Event that is being processed
  
  Context - Event Context

Returns: 
  None

--*/
{
  EFI_STATUS  Status;
  UINTN       BufferSize;
  EFI_HANDLE  Handle;
  UINTN       Index;
  UINTN       UpdateIndex;

  while (TRUE) {
    BufferSize = sizeof (Handle);
    Status = gBS->LocateHandle (
                    ByRegisterNotify,
                    &gEfiFirmwareVolumeBlockProtocolGuid,
                    mFvbRegistration,
                    &BufferSize,
                    &Handle
                    );
    if (EFI_ERROR (Status)) {
      //
      // Exit Path of While Loop....
      //
      break;
    }

    UpdateIndex = MAX_FVB_COUNT;
    for (Index = 0; Index < mFvbCount; Index++) {
      if (mFvbEntry[Index].Handle == Handle) {
        //
        //  If the handle is already in the table just update the protocol
        //
        UpdateIndex = Index;
        break;
      }
    }

    if (UpdateIndex == MAX_FVB_COUNT) {
      //
      // Use the next free slot for a new entry
      //
      UpdateIndex                   = mFvbCount++;;
      mFvbEntry[UpdateIndex].Handle = Handle;
    }
    //
    // The array does not have enough entries
    //
    ASSERT (UpdateIndex < MAX_FVB_COUNT);

    //
    //  Get the interface pointer and if it's ours, skip it
    //
    Status = gBS->HandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &mFvbEntry[UpdateIndex].Fvb);
    ASSERT_EFI_ERROR (Status);

    Status = gBS->HandleProtocol (Handle, &gEfiFvbExtensionProtocolGuid, &mFvbEntry[UpdateIndex].FvbExtension);
    if (Status != EFI_SUCCESS) {
      mFvbEntry[UpdateIndex].FvbExtension = NULL;
    }
  }
}

VOID
EFIAPI
FvbVirtualAddressChangeNotifyEvent (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
/*++

Routine Description:

  Convert all pointers in mFvbEntry after ExitBootServices.

Arguments:

  Event   - The Event that is being processed
  
  Context - Event Context

Returns:

  None

--*/
{
  UINTN Index;
  if (mFvbEntry != NULL) {
    for (Index = 0; Index < MAX_FVB_COUNT; Index++) {
      if (NULL != mFvbEntry[Index].Fvb) {
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetBlockSize);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetPhysicalAddress);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->GetVolumeAttributes);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->SetVolumeAttributes);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Read);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->Write);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb->EraseBlocks);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].Fvb);
      }

      if (NULL != mFvbEntry[Index].FvbExtension) {
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension->EraseFvbCustomBlock);
        EfiConvertPointer (0x0, (VOID **) &mFvbEntry[Index].FvbExtension);
      }
    }

    EfiConvertPointer (0x0, (VOID **) &mFvbEntry);
  }
}

EFI_STATUS
EFIAPI
FvbLibInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
/*++

Routine Description:
  Initialize globals and register Fvb Protocol notification function.

Arguments:
  None 

Returns: 
  EFI_SUCCESS

--*/
{
  UINTN Status;
  mFvbCount = 0;

  Status = gBS->AllocatePool (
                  EfiRuntimeServicesData,
                  (UINTN) sizeof (FVB_ENTRY) * MAX_FVB_COUNT,
                  (VOID *) &mFvbEntry
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  ZeroMem (mFvbEntry, sizeof (FVB_ENTRY) * MAX_FVB_COUNT);

  EfiCreateProtocolNotifyEvent (
    &gEfiFirmwareVolumeBlockProtocolGuid,
    EFI_TPL_CALLBACK,
    FvbNotificationEvent,
    NULL,
    &mFvbRegistration
    );

  //
  // Register SetVirtualAddressMap () notify function
  //
  //  Status = gBS->CreateEvent (
  //                EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
  //                EFI_TPL_NOTIFY,
  //                EfiRuntimeLibFvbVirtualNotifyEvent,
  //                NULL,
  //                &mEfiFvbVirtualNotifyEvent
  //                );
  //  ASSERT_EFI_ERROR (Status);
  //

  //
  // Register SetVirtualAddressMap () notify function
  //

  ASSERT_EFI_ERROR (Status);

  mEfiFvbInitialized = TRUE;

  return EFI_SUCCESS;
}
//
// The following functions wrap Fvb protocol in the Runtime Lib functions.
// The Instance translates into Fvb instance. The Fvb order defined by HOBs and
// thus the sequence of FVB protocol addition define Instance.
//
// EfiFvbInitialize () must be called before any of the following functions
// must be called.
//

EFI_STATUS
EfiFvbReadBlock (
  IN UINTN                                        Instance,
  IN EFI_LBA                                      Lba,
  IN UINTN                                        Offset,
  IN OUT UINTN                                    *NumBytes,
  IN UINT8                                        *Buffer
  )
/*++

Routine Description:
  Reads specified number of bytes into a buffer from the specified block

Arguments:
  Instance              - The FV instance to be read from
  Lba                   - The logical block address to be read from
  Offset                - Offset into the block at which to begin reading
  NumBytes              - Pointer that on input contains the total size of
                          the buffer. On output, it contains the total number
                          of bytes read
  Buffer                - Pointer to a caller allocated buffer that will be
                          used to hold the data read

Returns: 

  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->Read (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);
}

EFI_STATUS
EfiFvbWriteBlock (
  IN UINTN                                        Instance,
  IN EFI_LBA                                      Lba,
  IN UINTN                                        Offset,
  IN OUT UINTN                                    *NumBytes,
  IN UINT8                                        *Buffer
  )
/*++

Routine Description:
  Writes specified number of bytes from the input buffer to the block

Arguments:
  Instance              - The FV instance to be written to
  Lba                   - The starting logical block index to write to
  Offset                - Offset into the block at which to begin writing
  NumBytes              - Pointer that on input contains the total size of
                          the buffer. On output, it contains the total number
                          of bytes actually written
  Buffer                - Pointer to a caller allocated buffer that contains
                          the source for the write

Returns: 

  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->Write (mFvbEntry[Instance].Fvb, Lba, Offset, NumBytes, Buffer);
}

EFI_STATUS
EfiFvbEraseBlock (
  IN UINTN                                Instance,
  IN EFI_LBA                              Lba
  )
/*++

Routine Description:
  Erases and initializes a firmware volume block

Arguments:
  Instance              - The FV instance to be erased
  Lba                   - The logical block index to be erased
  
Returns: 

  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->EraseBlocks (mFvbEntry[Instance].Fvb, Lba, -1);
}

EFI_STATUS
EfiFvbGetVolumeAttributes (
  IN UINTN                                Instance,
  OUT EFI_FVB_ATTRIBUTES                  *Attributes
  )
/*++

Routine Description:
  Retrieves attributes, insures positive polarity of attribute bits, returns
  resulting attributes in output parameter

Arguments:
  Instance              - The FV instance whose attributes is going to be 
                          returned
  Attributes            - Output buffer which contains attributes

Returns: 
  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->GetVolumeAttributes (mFvbEntry[Instance].Fvb, Attributes);
}

EFI_STATUS
EfiFvbSetVolumeAttributes (
  IN UINTN                                Instance,
  IN EFI_FVB_ATTRIBUTES                   Attributes
  )
/*++

Routine Description:
  Modifies the current settings of the firmware volume according to the 
  input parameter, and returns the new setting of the volume

Arguments:
  Instance              - The FV instance whose attributes is going to be 
                          modified
  Attributes            - On input, it is a pointer to EFI_FVB_ATTRIBUTES 
                          containing the desired firmware volume settings.
                          On successful return, it contains the new settings
                          of the firmware volume

Returns: 
  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->SetVolumeAttributes (mFvbEntry[Instance].Fvb, &Attributes);
}

EFI_STATUS
EfiFvbGetPhysicalAddress (
  IN UINTN                                Instance,
  OUT EFI_PHYSICAL_ADDRESS                *BaseAddress
  )
/*++

Routine Description:
  Retrieves the physical address of a memory mapped FV

Arguments:
  Instance              - The FV instance whose base address is going to be
                          returned
  BaseAddress           - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS 
                          that on successful return, contains the base address
                          of the firmware volume. 

Returns: 

  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->GetPhysicalAddress (mFvbEntry[Instance].Fvb, BaseAddress);
}

EFI_STATUS
EfiFvbGetBlockSize (
  IN UINTN                                        Instance,
  IN EFI_LBA                                      Lba,
  OUT UINTN                                       *BlockSize,
  OUT UINTN                                       *NumOfBlocks
  )
/*++

Routine Description:
  Retrieve the size of a logical block

Arguments:
  Instance              - The FV instance whose block size is going to be
                          returned
  Lba                   - Indicates which block to return the size for.
  BlockSize             - A pointer to a caller allocated UINTN in which
                          the size of the block is returned
  NumOfBlocks           - a pointer to a caller allocated UINTN in which the
                          number of consecutive blocks starting with Lba is
                          returned. All blocks in this range have a size of
                          BlockSize

Returns: 
  EFI_SUCCESS           - The firmware volume was read successfully and 
                          contents are in Buffer
                          
  EFI_INVALID_PARAMETER - invalid parameter

--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  return mFvbEntry[Instance].Fvb->GetBlockSize (mFvbEntry[Instance].Fvb, Lba, BlockSize, NumOfBlocks);
}

EFI_STATUS
EfiFvbEraseCustomBlockRange (
  IN UINTN                                Instance,
  IN EFI_LBA                              StartLba,
  IN UINTN                                OffsetStartLba,
  IN EFI_LBA                              LastLba,
  IN UINTN                                OffsetLastLba
  )
/*++

Routine Description:
  Erases and initializes a specified range of a firmware volume

Arguments:
  Instance              - The FV instance to be erased
  StartLba              - The starting logical block index to be erased
  OffsetStartLba        - Offset into the starting block at which to 
                          begin erasing
  LastLba               - The last logical block index to be erased
  OffsetLastLba         - Offset into the last block at which to end erasing

Returns: 

  Status code
  
  EFI_INVALID_PARAMETER - invalid parameter
  
  EFI_UNSUPPORTED       - not support
  
--*/
{
  if (Instance >= mFvbCount) {
    return EFI_INVALID_PARAMETER;
  }

  if (!(mFvbEntry[Instance].FvbExtension)) {
    return EFI_UNSUPPORTED;
  }

  if (!(mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock)) {
    return EFI_UNSUPPORTED;
  }

  return mFvbEntry[Instance].FvbExtension->EraseFvbCustomBlock (
                                            mFvbEntry[Instance].FvbExtension,
                                            StartLba,
                                            OffsetStartLba,
                                            LastLba,
                                            OffsetLastLba
                                            );
}
