/** @file

  Copyright (c) 2008 - 2009, Apple Inc. 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/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;
}
