X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FPiSmmCore%2FInstallConfigurationTable.c;fp=MdeModulePkg%2FCore%2FPiSmmCore%2FInstallConfigurationTable.c;h=9623fae7f28adbed80752095b90026926ad1aa3d;hp=0000000000000000000000000000000000000000;hb=e42e94041f7c71a5e2e57154bd568f3c14fd6eec;hpb=713b77813bb80de2d1b8515f0f360ebb008a5284 diff --git a/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c b/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c new file mode 100644 index 0000000000..9623fae7f2 --- /dev/null +++ b/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c @@ -0,0 +1,161 @@ +/** @file + System Management System Table Services SmmInstallConfigurationTable service + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ 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; +}