/** @file
  Token Mapper

  Copyright (c) 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
    - Cm or CM   - Configuration Manager
    - Obj or OBJ - Object
**/

#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>

#include "TokenMapper.h"

/** Add a CmObjDesc to the TokenMapper.

  @param [in] TokenMapper   The TokenMapper instance.
  @param [in] Token         CmObj token.
  @param [in] ObjectId      CmObj ObjectId.
  @param [in] Size          CmObj Size.
  @param [in] Data          CmObj Data.
                            This memory is referenced, not copied.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    Buffer too small.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
**/
EFI_STATUS
EFIAPI
TokenMapperAddObject (
  IN  TOKEN_MAPPER     *TokenMapper,
  IN  CM_OBJECT_TOKEN  Token,
  IN  CM_OBJECT_ID     ObjectId,
  IN  UINT32           Size,
  IN  VOID             *Data
  )
{
  TOKEN_MAP_DESCRIPTOR  *TokenMapDesc;
  CM_OBJ_DESCRIPTOR     *CmObjDesc;

  if ((TokenMapper == NULL)                 ||
      (TokenMapper->TokenDescArray == NULL) ||
      (Size == 0)                           ||
      (Data == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (TokenMapper->ItemCount >= TokenMapper->MaxTokenDescCount) {
    ASSERT (0);
    return EFI_BUFFER_TOO_SMALL;
  }

  TokenMapDesc        = &TokenMapper->TokenDescArray[TokenMapper->ItemCount++];
  TokenMapDesc->Token = Token;
  CmObjDesc           = &TokenMapDesc->CmObjDesc;
  CmObjDesc->ObjectId = ObjectId;
  CmObjDesc->Size     = Size;

  // Point inside the finalized array.
  CmObjDesc->Data = Data;

  // Only EArchCommonObjCmRef CmObj can be added as
  // arrays (more than 1 elements).
  if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArchCommon) &&
      (GET_CM_OBJECT_ID (ObjectId) == EArchCommonObjCmRef))
  {
    CmObjDesc->Count = Size / sizeof (CM_ARCH_COMMON_OBJ_REF);
  } else if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) &&
             (GET_CM_OBJECT_ID (ObjectId) == EArmObjIdMappingArray))
  {
    CmObjDesc->Count = Size / sizeof (CM_ARM_ID_MAPPING);
  } else {
    CmObjDesc->Count = 1;
  }

  return EFI_SUCCESS;
}

/** Get a CmObjDesc from a ObjectId/Token couple.

  The Token parameter is not optional. An existing token must be provided.

  @param [in]  TokenMapper   The TokenMapper instance.
  @param [in]  Token         Token of the CmObj to search.
  @param [in]  ObjectId      Object Id of the CmObj to search.
  @param [out] CmObjDesc     CM_OBJ_DESCRIPTOR containing the CmObj searched.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
  @retval EFI_NOT_FOUND           Not found.
**/
EFI_STATUS
EFIAPI
TokenMapperGetObject (
  IN  TOKEN_MAPPER       *TokenMapper,
  IN  CM_OBJECT_TOKEN    Token,
  IN  CM_OBJECT_ID       ObjectId,
  OUT CM_OBJ_DESCRIPTOR  *CmObjDesc
  )
{
  UINTN                 Index;
  UINTN                 MaxCount;
  TOKEN_MAP_DESCRIPTOR  *TokenMapDesc;

  // Nothing to do.
  if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
    goto exit_handler;
  }

  if ((Token == CM_NULL_TOKEN)              ||
      (CmObjDesc == NULL)                   ||
      (TokenMapper == NULL)                 ||
      (TokenMapper->TokenDescArray == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  TokenMapDesc = TokenMapper->TokenDescArray;
  MaxCount     = TokenMapper->MaxTokenDescCount;
  for (Index = 0; Index < MaxCount; Index++) {
    if ((TokenMapDesc->CmObjDesc.ObjectId == ObjectId)  &&
        (TokenMapDesc->Token == Token))
    {
      CopyMem (
        CmObjDesc,
        &TokenMapDesc->CmObjDesc,
        sizeof (CM_OBJ_DESCRIPTOR)
        );
      return EFI_SUCCESS;
    }

    TokenMapDesc++;
  } // for

exit_handler:
  DEBUG ((
    DEBUG_INFO,
    "INFO: Requested CmObj of type 0x%x with token 0x%x"
    " not found in the dynamic repository\n.",
    ObjectId,
    Token
    ));
  return EFI_NOT_FOUND;
}

/** Initialise a TokenMapper.

  @param [in] TokenMapper       The TokenMapper to initialise.
  @param [in] DescriptorCount   Number of entries to allocate.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ALREADY_STARTED     Instance already initialised.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
**/
EFI_STATUS
EFIAPI
TokenMapperInitialise (
  IN  TOKEN_MAPPER  *TokenMapper,
  IN  UINTN         DescriptorCount
  )
{
  if (TokenMapper == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Nothing to do.
  if (DescriptorCount == 0) {
    return EFI_SUCCESS;
  }

  if (TokenMapper->TokenDescArray != NULL) {
    DEBUG ((DEBUG_ERROR, "ERROR: Token mapper already initialised\n."));
    ASSERT (0);
    return EFI_ALREADY_STARTED;
  }

  TokenMapper->TokenDescArray =
    AllocateZeroPool (sizeof (TOKEN_MAP_DESCRIPTOR) * DescriptorCount);
  if (TokenMapper->TokenDescArray == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  TokenMapper->MaxTokenDescCount = DescriptorCount;
  TokenMapper->ItemCount         = 0;

  return EFI_SUCCESS;
}

/** Shutdown a TokenMapper.

  @param [in] TokenMapper       The TokenMapper to shutdown.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   A parameter is invalid.
**/
EFI_STATUS
EFIAPI
TokenMapperShutdown (
  IN  TOKEN_MAPPER  *TokenMapper
  )
{
  // Nothing to do.
  if ((TokenMapper != NULL) && (TokenMapper->MaxTokenDescCount == 0)) {
    return EFI_SUCCESS;
  }

  if ((TokenMapper == NULL) ||
      (TokenMapper->TokenDescArray == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (TokenMapper->TokenDescArray);
  TokenMapper->TokenDescArray    = NULL;
  TokenMapper->MaxTokenDescCount = 0;

  return EFI_SUCCESS;
}
