]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / InstallConfigurationTable.c
1 /** @file
2 UEFI Miscellaneous boot Services InstallConfigurationTable service
3
4 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "DxeMain.h"
10
11 #define CONFIG_TABLE_SIZE_INCREASED 0x10
12
13 UINTN mSystemTableAllocateSize = 0;
14
15 /**
16 Boot Service called to add, modify, or remove a system configuration table from
17 the EFI System Table.
18
19 @param Guid Pointer to the GUID for the entry to add, update, or
20 remove
21 @param Table Pointer to the configuration table for the entry to add,
22 update, or remove, may be NULL.
23
24 @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
25 @return EFI_INVALID_PARAMETER Input GUID is NULL.
26 @return EFI_NOT_FOUND Attempted to delete non-existant entry
27 @return EFI_OUT_OF_RESOURCES Not enough memory available
28
29 **/
30 EFI_STATUS
31 EFIAPI
32 CoreInstallConfigurationTable (
33 IN EFI_GUID *Guid,
34 IN VOID *Table
35 )
36 {
37 UINTN Index;
38 EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
39 EFI_CONFIGURATION_TABLE *OldTable;
40
41 //
42 // If Guid is NULL, then this operation cannot be performed
43 //
44 if (Guid == NULL) {
45 return EFI_INVALID_PARAMETER;
46 }
47
48 EfiConfigurationTable = gDxeCoreST->ConfigurationTable;
49
50 //
51 // Search all the table for an entry that matches Guid
52 //
53 for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) {
54 if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) {
55 break;
56 }
57 }
58
59 if (Index < gDxeCoreST->NumberOfTableEntries) {
60 //
61 // A match was found, so this is either a modify or a delete operation
62 //
63 if (Table != NULL) {
64 //
65 // If Table is not NULL, then this is a modify operation.
66 // Modify the table entry and return.
67 //
68 gDxeCoreST->ConfigurationTable[Index].VendorTable = Table;
69
70 //
71 // Signal Configuration Table change
72 //
73 CoreNotifySignalList (Guid);
74
75 return EFI_SUCCESS;
76 }
77
78 //
79 // A match was found and Table is NULL, so this is a delete operation.
80 //
81 gDxeCoreST->NumberOfTableEntries--;
82
83 //
84 // Copy over deleted entry
85 //
86 CopyMem (
87 &(EfiConfigurationTable[Index]),
88 &(gDxeCoreST->ConfigurationTable[Index + 1]),
89 (gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
90 );
91
92 } else {
93
94 //
95 // No matching GUIDs were found, so this is an add operation.
96 //
97
98 if (Table == NULL) {
99 //
100 // If Table is NULL on an add operation, then return an error.
101 //
102 return EFI_NOT_FOUND;
103 }
104
105 //
106 // Assume that Index == gDxeCoreST->NumberOfTableEntries
107 //
108 if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {
109 //
110 // Allocate a table with one additional entry.
111 //
112 mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
113 EfiConfigurationTable = AllocateRuntimePool (mSystemTableAllocateSize);
114 if (EfiConfigurationTable == NULL) {
115 //
116 // If a new table could not be allocated, then return an error.
117 //
118 return EFI_OUT_OF_RESOURCES;
119 }
120
121 if (gDxeCoreST->ConfigurationTable != NULL) {
122 //
123 // Copy the old table to the new table.
124 //
125 CopyMem (
126 EfiConfigurationTable,
127 gDxeCoreST->ConfigurationTable,
128 Index * sizeof (EFI_CONFIGURATION_TABLE)
129 );
130
131 //
132 // Record the old table pointer.
133 //
134 OldTable = gDxeCoreST->ConfigurationTable;
135
136 //
137 // As the CoreInstallConfigurationTable() may be re-entered by CoreFreePool()
138 // in its calling stack, updating System table to the new table pointer must
139 // be done before calling CoreFreePool() to free the old table.
140 // It can make sure the gDxeCoreST->ConfigurationTable point to the new table
141 // and avoid the errors of use-after-free to the old table by the reenter of
142 // CoreInstallConfigurationTable() in CoreFreePool()'s calling stack.
143 //
144 gDxeCoreST->ConfigurationTable = EfiConfigurationTable;
145
146 //
147 // Free the old table after updating System Table to the new table pointer.
148 //
149 CoreFreePool (OldTable);
150 } else {
151 //
152 // Update System Table
153 //
154 gDxeCoreST->ConfigurationTable = EfiConfigurationTable;
155 }
156 }
157
158 //
159 // Fill in the new entry
160 //
161 CopyGuid ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid);
162 EfiConfigurationTable[Index].VendorTable = Table;
163
164 //
165 // This is an add operation, so increment the number of table entries
166 //
167 gDxeCoreST->NumberOfTableEntries++;
168 }
169
170 //
171 // Fix up the CRC-32 in the EFI System Table
172 //
173 CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
174
175 //
176 // Signal Configuration Table change
177 //
178 CoreNotifySignalList (Guid);
179
180 return EFI_SUCCESS;
181 }