/** @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 EArmObjCmRef CmObj can be added as arrays (more than 1 elements).
  if ((GET_CM_NAMESPACE_ID (ObjectId) == EObjNameSpaceArm) &&
      (GET_CM_OBJECT_ID (ObjectId) == EArmObjCmRef))
  {
    CmObjDesc->Count = Size / sizeof (CM_ARM_OBJ_REF);
  } 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;
}
