mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-04 05:25:45 +01:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10420 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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;
 | 
						|
}
 |