]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
1436aea4 11#define CONFIG_TABLE_SIZE_INCREASED 0x10\r
28a00297 12\r
1436aea4 13UINTN mSystemTableAllocateSize = 0;\r
28a00297 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
1436aea4
MK
33 IN EFI_GUID *Guid,\r
34 IN VOID *Table\r
28a00297 35 )\r
28a00297 36{\r
1436aea4
MK
37 UINTN Index;\r
38 EFI_CONFIGURATION_TABLE *EfiConfigurationTable;\r
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
28a00297 91 } else {\r
28a00297 92 //\r
93 // No matching GUIDs were found, so this is an add operation.\r
94 //\r
95\r
96 if (Table == NULL) {\r
97 //\r
98 // If Table is NULL on an add operation, then return an error.\r
99 //\r
100 return EFI_NOT_FOUND;\r
101 }\r
102\r
103 //\r
104 // Assume that Index == gDxeCoreST->NumberOfTableEntries\r
105 //\r
106 if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {\r
107 //\r
108 // Allocate a table with one additional entry.\r
109 //\r
110 mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));\r
1436aea4 111 EfiConfigurationTable = AllocateRuntimePool (mSystemTableAllocateSize);\r
28a00297 112 if (EfiConfigurationTable == NULL) {\r
113 //\r
114 // If a new table could not be allocated, then return an error.\r
115 //\r
116 return EFI_OUT_OF_RESOURCES;\r
117 }\r
118\r
119 if (gDxeCoreST->ConfigurationTable != NULL) {\r
120 //\r
121 // Copy the old table to the new table.\r
122 //\r
123 CopyMem (\r
124 EfiConfigurationTable,\r
125 gDxeCoreST->ConfigurationTable,\r
126 Index * sizeof (EFI_CONFIGURATION_TABLE)\r
127 );\r
128\r
129 //\r
322d827c 130 // Record the old table pointer.\r
28a00297 131 //\r
322d827c 132 OldTable = gDxeCoreST->ConfigurationTable;\r
28a00297 133\r
322d827c
SS
134 //\r
135 // As the CoreInstallConfigurationTable() may be re-entered by CoreFreePool()\r
136 // in its calling stack, updating System table to the new table pointer must\r
137 // be done before calling CoreFreePool() to free the old table.\r
138 // It can make sure the gDxeCoreST->ConfigurationTable point to the new table\r
139 // and avoid the errors of use-after-free to the old table by the reenter of\r
140 // CoreInstallConfigurationTable() in CoreFreePool()'s calling stack.\r
141 //\r
142 gDxeCoreST->ConfigurationTable = EfiConfigurationTable;\r
143\r
144 //\r
145 // Free the old table after updating System Table to the new table pointer.\r
146 //\r
147 CoreFreePool (OldTable);\r
148 } else {\r
149 //\r
150 // Update System Table\r
151 //\r
152 gDxeCoreST->ConfigurationTable = EfiConfigurationTable;\r
153 }\r
28a00297 154 }\r
155\r
156 //\r
157 // Fill in the new entry\r
158 //\r
e94a9ff7 159 CopyGuid ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid);\r
1436aea4 160 EfiConfigurationTable[Index].VendorTable = Table;\r
28a00297 161\r
162 //\r
163 // This is an add operation, so increment the number of table entries\r
164 //\r
165 gDxeCoreST->NumberOfTableEntries++;\r
166 }\r
167\r
168 //\r
169 // Fix up the CRC-32 in the EFI System Table\r
170 //\r
171 CalculateEfiHdrCrc (&gDxeCoreST->Hdr);\r
172\r
173 //\r
174 // Signal Configuration Table change\r
175 //\r
176 CoreNotifySignalList (Guid);\r
177\r
178 return EFI_SUCCESS;\r
179}\r