/** @file

  Copyright (c) 2008-2009, Apple Inc. All rights reserved.
  
  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.

**/

#include <PiPei.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/ExtractGuidedSectionLib.h>
#include <Library/PcdLib.h>
#include <Library/PrePiLib.h>

#define PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID { 0x385A982C, 0x2F49, 0x4043, { 0xA5, 0x1E, 0x49, 0x01, 0x02, 0x5C, 0x8B, 0x6B }}

typedef struct {
  UINT32                                  NumberOfExtractHandler;
  GUID                                    *ExtractHandlerGuidTable;
  EXTRACT_GUIDED_SECTION_DECODE_HANDLER   *ExtractDecodeHandlerTable;
  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *ExtractGetInfoHandlerTable;
} PRE_PI_EXTRACT_GUIDED_SECTION_DATA;

PRE_PI_EXTRACT_GUIDED_SECTION_DATA *
GetSavedData (
  VOID
  )
{
  EFI_HOB_GUID_TYPE *GuidHob;
  GUID              SavedDataGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID;

  GuidHob = GetFirstGuidHob(&SavedDataGuid);
  GuidHob++;
  
  return (PRE_PI_EXTRACT_GUIDED_SECTION_DATA *)GuidHob;
}

RETURN_STATUS
EFIAPI
ExtractGuidedSectionRegisterHandlers (
  IN CONST  GUID                                     *SectionGuid,
  IN        EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER  GetInfoHandler,
  IN        EXTRACT_GUIDED_SECTION_DECODE_HANDLER    DecodeHandler
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  *SavedData;
  UINT32                              Index;
  //
  // Check input paramter.
  //
  if (SectionGuid == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  SavedData = GetSavedData();

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], SectionGuid)) {
      break;
    }
  }

  //
  // If the guided handler has been registered before, only update its handler.
  //
  if (Index < SavedData->NumberOfExtractHandler) {
    SavedData->ExtractDecodeHandlerTable [Index] = DecodeHandler;
    SavedData->ExtractGetInfoHandlerTable [Index] = GetInfoHandler;
    return RETURN_SUCCESS;
  }
  
  //
  // Check the global table is enough to contain new Handler.
  //
  if (SavedData->NumberOfExtractHandler >= PcdGet32 (PcdMaximumGuidedExtractHandler)) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  //
  // Register new Handler and guid value.
  //
  CopyGuid (&SavedData->ExtractHandlerGuidTable [SavedData->NumberOfExtractHandler], SectionGuid);
  SavedData->ExtractDecodeHandlerTable [SavedData->NumberOfExtractHandler] = DecodeHandler;
  SavedData->ExtractGetInfoHandlerTable [SavedData->NumberOfExtractHandler++] = GetInfoHandler;
  
  return RETURN_SUCCESS;
}

UINTN
EFIAPI
ExtractGuidedSectionGetGuidList (
  IN OUT  GUID  **ExtractHandlerGuidTable
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  *SavedData;

  ASSERT(ExtractHandlerGuidTable != NULL);
  
  SavedData = GetSavedData();
  
  *ExtractHandlerGuidTable = SavedData->ExtractHandlerGuidTable;
  return SavedData->NumberOfExtractHandler;
}

RETURN_STATUS
EFIAPI
ExtractGuidedSectionGetInfo (
  IN  CONST VOID    *InputSection,
  OUT       UINT32  *OutputBufferSize,
  OUT       UINT32  *ScratchBufferSize,
  OUT       UINT16  *SectionAttribute   
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  *SavedData;
  UINT32                              Index;
  
  if (InputSection == NULL) {
    return RETURN_INVALID_PARAMETER;
  }
  
  ASSERT (OutputBufferSize != NULL);
  ASSERT (ScratchBufferSize != NULL);
  ASSERT (SectionAttribute != NULL);
 
  SavedData = GetSavedData();

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
      break;
    }
  }

  //
  // Not found, the input guided section is not supported. 
  //
  if (Index == SavedData->NumberOfExtractHandler) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // Call the match handler to getinfo for the input section data.
  //
  return SavedData->ExtractGetInfoHandlerTable [Index] (
            InputSection,
            OutputBufferSize,
            ScratchBufferSize,
            SectionAttribute
          );
}

RETURN_STATUS
EFIAPI
ExtractGuidedSectionDecode (
  IN  CONST VOID    *InputSection,
  OUT       VOID    **OutputBuffer,
  OUT       VOID    *ScratchBuffer,        OPTIONAL
  OUT       UINT32  *AuthenticationStatus  
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  *SavedData;
  UINT32                              Index;
  
  if (InputSection == NULL) {
    return RETURN_INVALID_PARAMETER;
  }
  
  ASSERT (OutputBuffer != NULL);
  ASSERT (AuthenticationStatus != NULL);

  SavedData = GetSavedData();

  //
  // Search the match registered GetInfo handler for the input guided section.
  //
  for (Index = 0; Index < SavedData->NumberOfExtractHandler; Index ++) {
    if (CompareGuid (&SavedData->ExtractHandlerGuidTable[Index], &(((EFI_GUID_DEFINED_SECTION *) InputSection)->SectionDefinitionGuid))) {
      break;
    }
  }

  //
  // Not found, the input guided section is not supported. 
  //
  if (Index == SavedData->NumberOfExtractHandler) {
    return RETURN_INVALID_PARAMETER;
  }

  //
  // Call the match handler to getinfo for the input section data.
  //
  return SavedData->ExtractDecodeHandlerTable [Index] (
            InputSection,
            OutputBuffer,
            ScratchBuffer,
            AuthenticationStatus
          );
}

RETURN_STATUS
EFIAPI
ExtractGuidedSectionLibConstructor (
  VOID
  )
{
  PRE_PI_EXTRACT_GUIDED_SECTION_DATA  SavedData;
  GUID                                HobGuid = PRE_PI_EXTRACT_GUIDED_SECTION_DATA_GUID;

  //
  // Allocate global pool space to store the registered handler and its guid value.
  //
  SavedData.ExtractHandlerGuidTable = (GUID *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(GUID));
  if (SavedData.ExtractHandlerGuidTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  SavedData.ExtractDecodeHandlerTable  = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_DECODE_HANDLER));
  if (SavedData.ExtractDecodeHandlerTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  SavedData.ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *)AllocatePool(PcdGet32(PcdMaximumGuidedExtractHandler) * sizeof(EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER));
  if (SavedData.ExtractGetInfoHandlerTable == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }
  
  //
  // the initialized number is Zero.
  //
  SavedData.NumberOfExtractHandler = 0;
  
  BuildGuidDataHob(&HobGuid, &SavedData, sizeof(SavedData));
  
  return RETURN_SUCCESS;
}
