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