1 /** @file 2 UEFI Miscellaneous boot Services InstallConfigurationTable service 3 4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "DxeMain.h" 16 17 #define CONFIG_TABLE_SIZE_INCREASED 0x10 18 19 UINTN mSystemTableAllocateSize = 0; 20 21 /** 22 Boot Service called to add, modify, or remove a system configuration table from 23 the EFI System Table. 24 25 @param Guid Pointer to the GUID for the entry to add, update, or 26 remove 27 @param Table Pointer to the configuration table for the entry to add, 28 update, or remove, may be NULL. 29 30 @return EFI_SUCCESS Guid, Table pair added, updated, or removed. 31 @return EFI_INVALID_PARAMETER Input GUID is NULL. 32 @return EFI_NOT_FOUND Attempted to delete non-existant entry 33 @return EFI_OUT_OF_RESOURCES Not enough memory available 34 35 **/ 36 EFI_STATUS 37 EFIAPI 38 CoreInstallConfigurationTable ( 39 IN EFI_GUID *Guid, 40 IN VOID *Table 41 ) 42 { 43 UINTN Index; 44 EFI_CONFIGURATION_TABLE *EfiConfigurationTable; 45 46 // 47 // If Guid is NULL, then this operation cannot be performed 48 // 49 if (Guid == NULL) { 50 return EFI_INVALID_PARAMETER; 51 } 52 53 EfiConfigurationTable = gDxeCoreST->ConfigurationTable; 54 55 // 56 // Search all the table for an entry that matches Guid 57 // 58 for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) { 59 if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) { 60 break; 61 } 62 } 63 64 if (Index < gDxeCoreST->NumberOfTableEntries) { 65 // 66 // A match was found, so this is either a modify or a delete operation 67 // 68 if (Table != NULL) { 69 // 70 // If Table is not NULL, then this is a modify operation. 71 // Modify the table enty and return. 72 // 73 gDxeCoreST->ConfigurationTable[Index].VendorTable = Table; 74 75 // 76 // Signal Configuration Table change 77 // 78 CoreNotifySignalList (Guid); 79 80 return EFI_SUCCESS; 81 } 82 83 // 84 // A match was found and Table is NULL, so this is a delete operation. 85 // 86 gDxeCoreST->NumberOfTableEntries--; 87 88 // 89 // Copy over deleted entry 90 // 91 CopyMem ( 92 &(EfiConfigurationTable[Index]), 93 &(gDxeCoreST->ConfigurationTable[Index + 1]), 94 (gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) 95 ); 96 97 } else { 98 99 // 100 // No matching GUIDs were found, so this is an add operation. 101 // 102 103 if (Table == NULL) { 104 // 105 // If Table is NULL on an add operation, then return an error. 106 // 107 return EFI_NOT_FOUND; 108 } 109 110 // 111 // Assume that Index == gDxeCoreST->NumberOfTableEntries 112 // 113 if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) { 114 // 115 // Allocate a table with one additional entry. 116 // 117 mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE)); 118 EfiConfigurationTable = AllocateRuntimePool (mSystemTableAllocateSize); 119 if (EfiConfigurationTable == NULL) { 120 // 121 // If a new table could not be allocated, then return an error. 122 // 123 return EFI_OUT_OF_RESOURCES; 124 } 125 126 if (gDxeCoreST->ConfigurationTable != NULL) { 127 // 128 // Copy the old table to the new table. 129 // 130 CopyMem ( 131 EfiConfigurationTable, 132 gDxeCoreST->ConfigurationTable, 133 Index * sizeof (EFI_CONFIGURATION_TABLE) 134 ); 135 136 // 137 // Free Old Table 138 // 139 CoreFreePool (gDxeCoreST->ConfigurationTable); 140 } 141 142 // 143 // Update System Table 144 // 145 gDxeCoreST->ConfigurationTable = EfiConfigurationTable; 146 } 147 148 // 149 // Fill in the new entry 150 // 151 CopyGuid ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid); 152 EfiConfigurationTable[Index].VendorTable = Table; 153 154 // 155 // This is an add operation, so increment the number of table entries 156 // 157 gDxeCoreST->NumberOfTableEntries++; 158 } 159 160 // 161 // Fix up the CRC-32 in the EFI System Table 162 // 163 CalculateEfiHdrCrc (&gDxeCoreST->Hdr); 164 165 // 166 // Signal Configuration Table change 167 // 168 CoreNotifySignalList (Guid); 169 170 return EFI_SUCCESS; 171 } 172