/** @file
  Provide generic extract guided section functions for PEI phase.

  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
  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.

**/

#include <PiPei.h>

#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.h>
#include <Library/ExtractGuidedSectionLib.h>

#define PEI_EXTRACT_HANDLER_INFO_SIGNATURE SIGNATURE_32 ('P', 'E', 'H', 'I')

typedef struct {
  UINT32                                  Signature;
  UINT32                                  NumberOfExtractHandler;
  GUID                                    *ExtractHandlerGuidTable;
  EXTRACT_GUIDED_SECTION_DECODE_HANDLER   *ExtractDecodeHandlerTable;
  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;
} PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO;

/**
  Build guid hob for the global memory to store the registered guid and Handler list.
  If GuidHob exists, HandlerInfo will be directly got from Guid hob data.

  @param[in, out]  InfoPointer   The pointer to pei handler information structure.

  @retval  RETURN_SUCCESS            Build Guid hob for the global memory space to store guid and function tables.
  @retval  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.
**/
RETURN_STATUS
PeiGetExtractGuidedSectionHandlerInfo (
  IN OUT PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer
  )
{
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
  EFI_PEI_HOB_POINTERS                    Hob;
  
  //
  // First try to get handler information from guid hob specified by CallerId.
  //
  Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GetHobList ());
  while (Hob.Raw != NULL) {
    if (CompareGuid (&(Hob.Guid->Name), &gEfiCallerIdGuid)) {
      HandlerInfo = (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *) GET_GUID_HOB_DATA (Hob.Guid);
      if (HandlerInfo->Signature == PEI_EXTRACT_HANDLER_INFO_SIGNATURE) {
        //
        // Update Table Pointer when hob start address is changed.
        //
        if (HandlerInfo->ExtractHandlerGuidTable != (GUID *) (HandlerInfo + 1)) {
          HandlerInfo->ExtractHandlerGuidTable    = (GUID *) (HandlerInfo + 1);
          HandlerInfo->ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
                                                      (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + 
                                                      PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
                                                     );
          HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
                                                      (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + 
                                                      PcdGet32 (PcdMaximumGuidedExtractHandler) * 
                                                      sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)
                                                     );
        }
        //
        // Return HandlerInfo pointer.
        //
        *InfoPointer = HandlerInfo;
        return EFI_SUCCESS;
      }
    }
    Hob.Raw = GET_NEXT_HOB (Hob);
    Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, Hob.Raw);
  }
  
  //
  // If Guid Hob is not found, Build CallerId Guid hob to store Handler Info
  //
  HandlerInfo = BuildGuidHob (
                 &gEfiCallerIdGuid, 
                 sizeof (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO) +
                 PcdGet32 (PcdMaximumGuidedExtractHandler) * 
                 (sizeof (GUID) + sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) + sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER))
                );
  if (HandlerInfo == NULL) {
    //
    // No enough resource to build guid hob.
    //
    *InfoPointer = NULL;
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Init HandlerInfo structure
  //
  HandlerInfo->Signature = PEI_EXTRACT_HANDLER_INFO_SIGNATURE;
  HandlerInfo->NumberOfExtractHandler     = 0;
  HandlerInfo->ExtractHandlerGuidTable    = (GUID *) (HandlerInfo + 1);
  HandlerInfo->ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) (
                                              (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + 
                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID)
                                             );
  HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) (
                                              (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + 
                                              PcdGet32 (PcdMaximumGuidedExtractHandler) * 
                                              sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER)
                                             );
  //
  // return the created HandlerInfo.
  //
  *InfoPointer = HandlerInfo;
  return EFI_SUCCESS;
}

/**
  Retrieve the list GUIDs that have been registered through ExtractGuidedSectionRegisterHandlers().

  Sets ExtractHandlerGuidTable so it points at a callee allocated array of registered GUIDs.
  The total number of GUIDs in the array are returned. Since the array of GUIDs is callee allocated
  and caller must treat this array of GUIDs as read-only data. 
  If ExtractHandlerGuidTable is NULL, then ASSERT().

  @param[out]  ExtractHandlerGuidTable  A pointer to the array of GUIDs that have been registered through
                                        ExtractGuidedSectionRegisterHandlers().

  @return the number of the supported extract guided Handler.

**/
UINTN
EFIAPI
ExtractGuidedSectionGetGuidList (
  OUT  GUID  **ExtractHandlerGuidTable
  )
{
  EFI_STATUS Status;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

  ASSERT (ExtractHandlerGuidTable != NULL);

  //
  // Get all registered handler information
  //
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    *ExtractHandlerGuidTable = NULL;
    return 0;
  }

  //
  // Get GuidTable and Table Number
  //
  ASSERT (HandlerInfo != NULL);
  *ExtractHandlerGuidTable = HandlerInfo->ExtractHandlerGuidTable;
  return HandlerInfo->NumberOfExtractHandler;
}

/**
  Registers handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and EXTRACT_GUIDED_SECTION_DECODE_HANDLER
  for a specific GUID section type.

  Registers the handlers specified by GetInfoHandler and DecodeHandler with the GUID specified by SectionGuid.
  If the GUID value specified by SectionGuid has already been registered, then return RETURN_ALREADY_STARTED.
  If there are not enough resources available to register the handlers  then RETURN_OUT_OF_RESOURCES is returned.
  
  If SectionGuid is NULL, then ASSERT().
  If GetInfoHandler is NULL, then ASSERT().
  If DecodeHandler is NULL, then ASSERT().

  @param[in]  SectionGuid    A pointer to the GUID associated with the the handlers
                             of the GUIDed section type being registered.
  @param[in]  GetInfoHandler The pointer to a function that examines a GUIDed section and returns the
                             size of the decoded buffer and the size of an optional scratch buffer
                             required to actually decode the data in a GUIDed section.
  @param[in]  DecodeHandler  The pointer to a function that decodes a GUIDed section into a caller
                             allocated output buffer. 

  @retval  RETURN_SUCCESS           The handlers were registered.
  @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources available to register the handlers.

**/
RETURN_STATUS
EFIAPI
ExtractGuidedSectionRegisterHandlers (
  IN CONST  GUID                                     *SectionGuid,
  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,
  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler
  )
{
  EFI_STATUS Status;
  UINT32     Index;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;

  //
  // Check input parameter
  //
  ASSERT (SectionGuid != NULL);
  ASSERT (GetInfoHandler != NULL);
  ASSERT (DecodeHandler != NULL);



  //
  // Get the registered handler information
  //
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  ASSERT (HandlerInfo != NULL);
  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {
      //
      // If the guided handler has been registered before, only update its handler.
      //
      HandlerInfo->ExtractDecodeHandlerTable [Index] = DecodeHandler;
      HandlerInfo->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
      return RETURN_SUCCESS;
    }
  }

  //
  // Check the global table is enough to contain new Handler.
  //
  if (HandlerInfo->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  //
  // Register new Handler and guid value.
  //
  CopyGuid (HandlerInfo->ExtractHandlerGuidTable + HandlerInfo->NumberOfExtractHandler, SectionGuid);
  HandlerInfo->ExtractDecodeHandlerTable [HandlerInfo->NumberOfExtractHandler] = DecodeHandler;
  HandlerInfo->ExtractGetInfoHandlerTable [HandlerInfo->NumberOfExtractHandler++] = GetInfoHandler;

  //
  // Build the Guided Section GUID HOB to record the GUID itself.
  // Then the content of the GUIDed HOB will be the same as the GUID value itself.
  //
  BuildGuidDataHob (
    (EFI_GUID *) SectionGuid,
    (VOID *) SectionGuid,
    sizeof (GUID)
    );

  return RETURN_SUCCESS;
}

/**
  Retrieves a GUID from a GUIDed section and uses that GUID to select an associated handler of type
  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
  The selected handler is used to retrieve and return the size of the decoded buffer and the size of an
  optional scratch buffer required to actually decode the data in a GUIDed section.

  Examines a GUIDed section specified by InputSection.  
  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
  then RETURN_UNSUPPORTED is returned.  
  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler 
  of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
  is used to retrieve the OututBufferSize, ScratchSize, and Attributes values. The return status from the handler of
  type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER is returned.
  
  If InputSection is NULL, then ASSERT().
  If OutputBufferSize is NULL, then ASSERT().
  If ScratchBufferSize is NULL, then ASSERT().
  If SectionAttribute is NULL, then ASSERT().

  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.
  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required if the buffer
                                 specified by InputSection were decoded.
  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space if the buffer specified by
                                 InputSection were decoded.
  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section.  See the Attributes field of
                                 EFI_GUID_DEFINED_SECTION in the PI Specification.

  @retval  RETURN_SUCCESS      Get the required information successfully.
  @retval  RETURN_UNSUPPORTED  The GUID from the section specified by InputSection does not match any of
                               the GUIDs registered with ExtractGuidedSectionRegisterHandlers().
  @retval  Others              The return status from the handler associated with the GUID retrieved from
                               the section specified by InputSection.

**/
RETURN_STATUS
EFIAPI
ExtractGuidedSectionGetInfo (
  IN  CONST VOID    *InputSection,
  OUT       UINT32  *OutputBufferSize,
  OUT       UINT32  *ScratchBufferSize,
  OUT       UINT16  *SectionAttribute   
  )
{
  UINT32 Index;
  EFI_STATUS Status;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
  EFI_GUID *SectionDefinitionGuid;
  
  //
  // Check input parameter
  //
  ASSERT (InputSection != NULL);
  ASSERT (OutputBufferSize != NULL);
  ASSERT (ScratchBufferSize != NULL);
  ASSERT (SectionAttribute != NULL);

  //
  // Get all registered handler information.
  //
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (IS_SECTION2 (InputSection)) {
    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);
  } else {
    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);
  }

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  ASSERT (HandlerInfo != NULL);
  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {
      //
      // Call the match handler to get information for the input section data.
      //
      return HandlerInfo->ExtractGetInfoHandlerTable [Index] (
                InputSection,
                OutputBufferSize,
                ScratchBufferSize,
                SectionAttribute
              );
    }
  }

  //
  // Not found, the input guided section is not supported. 
  //
  return RETURN_UNSUPPORTED;
}

/**
  Retrieves the GUID from a GUIDed section and uses that GUID to select an associated handler of type
  EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers().
  The selected handler is used to decode the data in a GUIDed section and return the result in a caller
  allocated output buffer.

  Decodes the GUIDed section specified by InputSection.  
  If GUID for InputSection does not match any of the GUIDs registered through ExtractGuidedSectionRegisterHandlers(),
  then RETURN_UNSUPPORTED is returned.  
  If the GUID of InputSection does match the GUID that this handler supports, then the the associated handler
  of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER that was registered with ExtractGuidedSectionRegisterHandlers()
  is used to decode InputSection into the buffer specified by OutputBuffer and the authentication status of this
  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the data in InputSection,
  then OutputBuffer is set to point at the data in InputSection.  Otherwise, the decoded data will be placed in caller
  allocated buffer specified by OutputBuffer.    This function is responsible for computing the  EFI_AUTH_STATUS_PLATFORM_OVERRIDE
  bit of in AuthenticationStatus.  The return status from the handler of type EXTRACT_GUIDED_SECTION_DECODE_HANDLER is returned. 
   
  If InputSection is NULL, then ASSERT().
  If OutputBuffer is NULL, then ASSERT().
  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().
  If AuthenticationStatus is NULL, then ASSERT().  

  @param[in]  InputSection   A pointer to a GUIDed section of an FFS formatted file.
  @param[out] OutputBuffer   A pointer to a buffer that contains the result of a decode operation. 
  @param[in]  ScratchBuffer  A caller allocated buffer that may be required by this function as a scratch buffer to perform the decode operation. 
  @param[out] AuthenticationStatus 
                             A pointer to the authentication status of the decoded output buffer. See the definition
                             of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI section of the PI
                             Specification.

  @retval  RETURN_SUCCESS           The buffer specified by InputSection was decoded.
  @retval  RETURN_UNSUPPORTED       The section specified by InputSection does not match the GUID this handler supports.
  @retval  RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded.

**/
RETURN_STATUS
EFIAPI
ExtractGuidedSectionDecode (
  IN  CONST VOID    *InputSection,
  OUT       VOID    **OutputBuffer,
  IN        VOID    *ScratchBuffer,        OPTIONAL
  OUT       UINT32  *AuthenticationStatus  
  )
{
  UINT32     Index;
  EFI_STATUS Status;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo;
  EFI_GUID *SectionDefinitionGuid;
  
  //
  // Check input parameter
  //
  ASSERT (InputSection != NULL);
  ASSERT (OutputBuffer != NULL);
  ASSERT (AuthenticationStatus != NULL);

  //
  // Get all registered handler information.
  //  
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (IS_SECTION2 (InputSection)) {
    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION2 *) InputSection)->SectionDefinitionGuid);
  } else {
    SectionDefinitionGuid = &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid);
  }

  //
  // Search the match registered Extract handler for the input guided section.
  //
  ASSERT (HandlerInfo != NULL);
  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionDefinitionGuid)) {
      //
      // Call the match handler to extract raw data for the input guided section.
      //
      return HandlerInfo->ExtractDecodeHandlerTable [Index] (
                InputSection,
                OutputBuffer,
                ScratchBuffer,
                AuthenticationStatus
              );
    }
  }

  //
  // Not found, the input guided section is not supported. 
  //
  return RETURN_UNSUPPORTED;
}

/**
  Retrieves handlers of type EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER and 
  EXTRACT_GUIDED_SECTION_DECODE_HANDLER for a specific GUID section type.
  
  Retrieves the handlers associated with SectionGuid and returns them in 
  GetInfoHandler and DecodeHandler.

  If the GUID value specified by SectionGuid has not been registered, then 
  return RETURN_NOT_FOUND.
  
  If SectionGuid is NULL, then ASSERT().

  @param[in]  SectionGuid    A pointer to the GUID associated with the handlersof the GUIDed 
                             section type being retrieved.
  @param[out] GetInfoHandler Pointer to a function that examines a GUIDed section and returns 
                             the size of the decoded buffer and the size of an optional scratch 
                             buffer required to actually decode the data in a GUIDed section.  
                             This is an optional parameter that may be NULL. If it is NULL, then 
                             the previously registered handler is not returned.
  @param[out] DecodeHandler  Pointer to a function that decodes a GUIDed section into a caller
                             allocated output buffer. This is an optional parameter that may be NULL.
                             If it is NULL, then the previously registered handler is not returned.

  @retval  RETURN_SUCCESS     The handlers were retrieved.
  @retval  RETURN_NOT_FOUND   No handlers have been registered with the specified GUID.

**/
RETURN_STATUS
EFIAPI
ExtractGuidedSectionGetHandlers (
  IN CONST   GUID                                     *SectionGuid,
  OUT        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  *GetInfoHandler,  OPTIONAL
  OUT        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    *DecodeHandler    OPTIONAL
  )
{
  EFI_STATUS                               Status;
  UINT32                                   Index;
  PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO  *HandlerInfo;

  //
  // Check input parameter
  //
  ASSERT (SectionGuid != NULL);

  //
  // Get the registered handler information
  //
  Status = PeiGetExtractGuidedSectionHandlerInfo (&HandlerInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  ASSERT (HandlerInfo != NULL);
  for (Index = 0; Index < HandlerInfo->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (HandlerInfo->ExtractHandlerGuidTable + Index, SectionGuid)) {

      //
      // If the guided handler has been registered before, then return the registered handlers.
      //
      if (GetInfoHandler != NULL) {
        *GetInfoHandler = HandlerInfo->ExtractGetInfoHandlerTable[Index];
      }
      if (DecodeHandler != NULL) {
        *DecodeHandler = HandlerInfo->ExtractDecodeHandlerTable[Index];
      }
      return RETURN_SUCCESS;
    }
  }
  return RETURN_NOT_FOUND;
}
