/** @file
  System Management System Table Services SmmInstallConfigurationTable service

  Copyright (c) 2009 - 2010, 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 "PiSmmCore.h"

#define CONFIG_TABLE_SIZE_INCREASED 0x10

UINTN  mSmmSystemTableAllocateSize = 0;

/**
  The SmmInstallConfigurationTable() function is used to maintain the list
  of configuration tables that are stored in the System Management System
  Table.  The list is stored as an array of (GUID, Pointer) pairs.  The list
  must be allocated from pool memory with PoolType set to EfiRuntimeServicesData.

  @param  SystemTable      A pointer to the SMM System Table (SMST).
  @param  Guid             A pointer to the GUID for the entry to add, update, or remove.
  @param  Table            A pointer to the buffer of the table to add.
  @param  TableSize        The size of the table to install.

  @retval EFI_SUCCESS           The (Guid, Table) pair was added, updated, or removed.
  @retval EFI_INVALID_PARAMETER Guid is not valid.
  @retval EFI_NOT_FOUND         An attempt was made to delete a non-existent entry.
  @retval EFI_OUT_OF_RESOURCES  There is not enough memory available to complete the operation.

**/
EFI_STATUS
EFIAPI
SmmInstallConfigurationTable (
  IN  CONST EFI_SMM_SYSTEM_TABLE2  *SystemTable,
  IN  CONST EFI_GUID               *Guid,
  IN  VOID                         *Table,
  IN  UINTN                        TableSize
  )
{
  UINTN                    Index;
  EFI_CONFIGURATION_TABLE  *ConfigurationTable;

  //
  // If Guid is NULL, then this operation cannot be performed
  //
  if (Guid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ConfigurationTable = gSmmCoreSmst.SmmConfigurationTable;

  //
  // Search all the table for an entry that matches Guid
  //
  for (Index = 0; Index < gSmmCoreSmst.NumberOfTableEntries; Index++) {
    if (CompareGuid (Guid, &(ConfigurationTable[Index].VendorGuid))) {
      break;
    }
  }

  if (Index < gSmmCoreSmst.NumberOfTableEntries) {
    //
    // A match was found, so this is either a modify or a delete operation
    //
    if (Table != NULL) {
      //
      // If Table is not NULL, then this is a modify operation.
      // Modify the table enty and return.
      //
      ConfigurationTable[Index].VendorTable = Table;
      return EFI_SUCCESS;
    }

    //
    // A match was found and Table is NULL, so this is a delete operation.
    //
    gSmmCoreSmst.NumberOfTableEntries--;

    //
    // Copy over deleted entry
    //
    CopyMem (
      &(ConfigurationTable[Index]),
      &(ConfigurationTable[Index + 1]),
      (gSmmCoreSmst.NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
      );

  } else {
    //
    // No matching GUIDs were found, so this is an add operation.
    //
    if (Table == NULL) {
      //
      // If Table is NULL on an add operation, then return an error.
      //
      return EFI_NOT_FOUND;
    }

    //
    // Assume that Index == gSmmCoreSmst.NumberOfTableEntries
    //
    if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSmmSystemTableAllocateSize) {
      //
      // Allocate a table with one additional entry.
      //
      mSmmSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
      ConfigurationTable = AllocatePool (mSmmSystemTableAllocateSize);
      if (ConfigurationTable == NULL) {
        //
        // If a new table could not be allocated, then return an error.
        //
        return EFI_OUT_OF_RESOURCES;
      }

      if (gSmmCoreSmst.SmmConfigurationTable != NULL) {
        //
        // Copy the old table to the new table.
        //
        CopyMem (
          ConfigurationTable,
          gSmmCoreSmst.SmmConfigurationTable,
          Index * sizeof (EFI_CONFIGURATION_TABLE)
          );

        //
        // Free Old Table
        //
        FreePool (gSmmCoreSmst.SmmConfigurationTable);
      }

      //
      // Update System Table
      //
      gSmmCoreSmst.SmmConfigurationTable = ConfigurationTable;
    }

    //
    // Fill in the new entry
    //
    CopyGuid ((VOID *)&ConfigurationTable[Index].VendorGuid, Guid);
    ConfigurationTable[Index].VendorTable = Table;

    //
    // This is an add operation, so increment the number of table entries
    //
    gSmmCoreSmst.NumberOfTableEntries++;
  }

  //
  // CRC-32 field is ignorable for SMM System Table and should be set to zero
  //

  return EFI_SUCCESS;
}
