summaryrefslogtreecommitdiff
path: root/Core/CORE_DXE/InstallConfigurationTable.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_DXE/InstallConfigurationTable.c')
-rw-r--r--Core/CORE_DXE/InstallConfigurationTable.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/Core/CORE_DXE/InstallConfigurationTable.c b/Core/CORE_DXE/InstallConfigurationTable.c
new file mode 100644
index 0000000..8aea9bc
--- /dev/null
+++ b/Core/CORE_DXE/InstallConfigurationTable.c
@@ -0,0 +1,230 @@
+/*++
+
+Copyright (c) 2004 - 2007, 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.
+
+Module Name:
+
+ InstallConfigurationTable.c
+
+
+Abstract:
+
+ Tiano Miscellaneous Services InstallConfigurationTable service
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+#define CONFIG_TABLE_SIZE_INCREASED 0x10
+
+UINTN mSystemTableAllocateSize = 0;
+
+
+EFI_STATUS
+CoreGetConfigTable (
+ IN EFI_GUID *Guid,
+ OUT VOID **Table
+ )
+/*++
+
+Routine Description:
+
+ Find a config table by name in system table's ConfigurationTable.
+
+Arguments:
+
+ Guid - The table name to look for
+
+ Table - Pointer of the config table
+
+Returns:
+
+ EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
+
+ EFI_SUCCESS - Table successfully found.
+
+--*/
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ *Table = gST->ConfigurationTable[Index].VendorTable;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreInstallConfigurationTable (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ )
+/*++
+
+Routine Description:
+
+ Boot Service called to add, modify, or remove a system configuration table from
+ the EFI System Table.
+
+Arguments:
+
+ Guid - Pointer to the GUID for the entry to add, update, or remove
+ Table - Pointer to the configuration table for the entry to add, update, or
+ remove, may be NULL.
+
+Returns:
+
+ EFI_SUCCESS Guid, Table pair added, updated, or removed.
+ EFI_INVALID_PARAMETER Input GUID not valid.
+ EFI_NOT_FOUND Attempted to delete non-existant entry
+ EFI_OUT_OF_RESOURCES Not enough memory available
+
+--*/
+{
+ UINTN Index;
+ EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
+
+ //
+ // If Guid is NULL, then this operation cannot be performed
+ //
+ if (Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ EfiConfigurationTable = gST->ConfigurationTable;
+
+ //
+ // Search all the table for an entry that matches Guid
+ //
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ break;
+ }
+ }
+
+ if (Index < gST->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.
+ //
+ gST->ConfigurationTable[Index].VendorTable = Table;
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Signal Configuration Table change
+ //
+ CoreNotifySignalList (Guid);
+#endif
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // A match was found and Table is NULL, so this is a delete operation.
+ //
+ gST->NumberOfTableEntries--;
+
+ //
+ // Copy over deleted entry
+ //
+ EfiCommonLibCopyMem (
+ &(EfiConfigurationTable[Index]),
+ &(gST->ConfigurationTable[Index + 1]),
+ (gST->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 == gST->NumberOfTableEntries
+ //
+ if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {
+ //
+ // Allocate a table with one additional entry.
+ //
+ mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
+ EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize);
+ if (EfiConfigurationTable == NULL) {
+ //
+ // If a new table could not be allocated, then return an error.
+ //
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (gST->ConfigurationTable != NULL) {
+ //
+ // Copy the old table to the new table.
+ //
+ EfiCommonLibCopyMem (
+ EfiConfigurationTable,
+ gST->ConfigurationTable,
+ Index * sizeof (EFI_CONFIGURATION_TABLE)
+ );
+
+ //
+ // Free Old Table
+ //
+ CoreFreePool (gST->ConfigurationTable);
+ }
+
+ //
+ // Update System Table
+ //
+ gST->ConfigurationTable = EfiConfigurationTable;
+ }
+
+ //
+ // Fill in the new entry
+ //
+ EfiConfigurationTable[Index].VendorGuid = *Guid;
+ EfiConfigurationTable[Index].VendorTable = Table;
+
+ //
+ // This is an add operation, so increment the number of table entries
+ //
+ gST->NumberOfTableEntries++;
+ }
+
+ //
+ // Fix up the CRC-32 in the EFI System Table
+ //
+ CalculateEfiHdrCrc (&gST->Hdr);
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Signal Configuration Table change
+ //
+ CoreNotifySignalList (Guid);
+#endif
+
+ return EFI_SUCCESS;
+}