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