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