TianoCore EDK2 master
Loading...
Searching...
No Matches
Handle.c
Go to the documentation of this file.
1
9#include "PiSmmCore.h"
10
11//
12// mProtocolDatabase - A list of all protocols in the system. (simple list for now)
13// gHandleList - A list of all the handles in the system
14//
15LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
16LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
17
29 IN EFI_HANDLE UserHandle
30 )
31{
32 IHANDLE *Handle;
33
34 Handle = (IHANDLE *)UserHandle;
35 if (Handle == NULL) {
36 return EFI_INVALID_PARAMETER;
37 }
38
39 if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
40 return EFI_INVALID_PARAMETER;
41 }
42
43 return EFI_SUCCESS;
44}
45
57 IN EFI_GUID *Protocol,
58 IN BOOLEAN Create
59 )
60{
61 LIST_ENTRY *Link;
62 PROTOCOL_ENTRY *Item;
63 PROTOCOL_ENTRY *ProtEntry;
64
65 //
66 // Search the database for the matching GUID
67 //
68
69 ProtEntry = NULL;
70 for (Link = mProtocolDatabase.ForwardLink;
71 Link != &mProtocolDatabase;
72 Link = Link->ForwardLink)
73 {
74 Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
75 if (CompareGuid (&Item->ProtocolID, Protocol)) {
76 //
77 // This is the protocol entry
78 //
79 ProtEntry = Item;
80 break;
81 }
82 }
83
84 //
85 // If the protocol entry was not found and Create is TRUE, then
86 // allocate a new entry
87 //
88 if ((ProtEntry == NULL) && Create) {
89 ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));
90 if (ProtEntry != NULL) {
91 //
92 // Initialize new protocol entry structure
93 //
94 ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
95 CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol);
96 InitializeListHead (&ProtEntry->Protocols);
97 InitializeListHead (&ProtEntry->Notify);
98
99 //
100 // Add it to protocol database
101 //
102 InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
103 }
104 }
105
106 return ProtEntry;
107}
108
123 IN IHANDLE *Handle,
124 IN EFI_GUID *Protocol,
125 IN VOID *Interface
126 )
127{
128 PROTOCOL_INTERFACE *Prot;
129 PROTOCOL_ENTRY *ProtEntry;
130 LIST_ENTRY *Link;
131
132 Prot = NULL;
133
134 //
135 // Lookup the protocol entry for this protocol ID
136 //
137 ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
138 if (ProtEntry != NULL) {
139 //
140 // Look at each protocol interface for any matches
141 //
142 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
143 //
144 // If this protocol interface matches, remove it
145 //
146 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
147 if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) {
148 break;
149 }
150
151 Prot = NULL;
152 }
153 }
154
155 return Prot;
156}
157
173EFIAPI
175 IN OUT EFI_HANDLE *UserHandle,
176 IN EFI_GUID *Protocol,
177 IN EFI_INTERFACE_TYPE InterfaceType,
178 IN VOID *Interface
179 )
180{
182 UserHandle,
183 Protocol,
184 InterfaceType,
185 Interface,
186 TRUE
187 );
188}
189
209 IN OUT EFI_HANDLE *UserHandle,
210 IN EFI_GUID *Protocol,
211 IN EFI_INTERFACE_TYPE InterfaceType,
212 IN VOID *Interface,
213 IN BOOLEAN Notify
214 )
215{
216 PROTOCOL_INTERFACE *Prot;
217 PROTOCOL_ENTRY *ProtEntry;
218 IHANDLE *Handle;
219 EFI_STATUS Status;
220 VOID *ExistingInterface;
221
222 //
223 // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
224 // Also added check for invalid UserHandle and Protocol pointers.
225 //
226 if ((UserHandle == NULL) || (Protocol == NULL)) {
227 return EFI_INVALID_PARAMETER;
228 }
229
230 if (InterfaceType != EFI_NATIVE_INTERFACE) {
231 return EFI_INVALID_PARAMETER;
232 }
233
234 //
235 // Print debug message
236 //
237 DEBUG ((DEBUG_LOAD | DEBUG_INFO, "SmmInstallProtocolInterface: %g %p\n", Protocol, Interface));
238
239 Status = EFI_OUT_OF_RESOURCES;
240 Prot = NULL;
241 Handle = NULL;
242
243 if (*UserHandle != NULL) {
244 Status = SmmHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
245 if (!EFI_ERROR (Status)) {
246 return EFI_INVALID_PARAMETER;
247 }
248 }
249
250 //
251 // Lookup the Protocol Entry for the requested protocol
252 //
253 ProtEntry = SmmFindProtocolEntry (Protocol, TRUE);
254 if (ProtEntry == NULL) {
255 goto Done;
256 }
257
258 //
259 // Allocate a new protocol interface structure
260 //
261 Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));
262 if (Prot == NULL) {
263 Status = EFI_OUT_OF_RESOURCES;
264 goto Done;
265 }
266
267 //
268 // If caller didn't supply a handle, allocate a new one
269 //
270 Handle = (IHANDLE *)*UserHandle;
271 if (Handle == NULL) {
272 Handle = AllocateZeroPool (sizeof (IHANDLE));
273 if (Handle == NULL) {
274 Status = EFI_OUT_OF_RESOURCES;
275 goto Done;
276 }
277
278 //
279 // Initialize new handler structure
280 //
281 Handle->Signature = EFI_HANDLE_SIGNATURE;
282 InitializeListHead (&Handle->Protocols);
283
284 //
285 // Add this handle to the list global list of all handles
286 // in the system
287 //
288 InsertTailList (&gHandleList, &Handle->AllHandles);
289 } else {
290 Status = SmmValidateHandle (Handle);
291 if (EFI_ERROR (Status)) {
292 DEBUG ((DEBUG_ERROR, "SmmInstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
293 goto Done;
294 }
295 }
296
297 //
298 // Each interface that is added must be unique
299 //
300 ASSERT (SmmFindProtocolInterface (Handle, Protocol, Interface) == NULL);
301
302 //
303 // Initialize the protocol interface structure
304 //
305 Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
306 Prot->Handle = Handle;
307 Prot->Protocol = ProtEntry;
308 Prot->Interface = Interface;
309
310 //
311 // Add this protocol interface to the head of the supported
312 // protocol list for this handle
313 //
314 InsertHeadList (&Handle->Protocols, &Prot->Link);
315
316 //
317 // Add this protocol interface to the tail of the
318 // protocol entry
319 //
320 InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
321
322 //
323 // Notify the notification list for this protocol
324 //
325 if (Notify) {
326 SmmNotifyProtocol (Prot);
327 }
328
329 Status = EFI_SUCCESS;
330
331Done:
332 if (!EFI_ERROR (Status)) {
333 //
334 // Return the new handle back to the caller
335 //
336 *UserHandle = Handle;
337 } else {
338 //
339 // There was an error, clean up
340 //
341 if (Prot != NULL) {
342 FreePool (Prot);
343 }
344
345 DEBUG ((DEBUG_ERROR, "SmmInstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
346 }
347
348 return Status;
349}
350
365EFIAPI
367 IN EFI_HANDLE UserHandle,
368 IN EFI_GUID *Protocol,
369 IN VOID *Interface
370 )
371{
372 EFI_STATUS Status;
373 IHANDLE *Handle;
374 PROTOCOL_INTERFACE *Prot;
375
376 //
377 // Check that Protocol is valid
378 //
379 if (Protocol == NULL) {
380 return EFI_INVALID_PARAMETER;
381 }
382
383 //
384 // Check that UserHandle is a valid handle
385 //
386 Status = SmmValidateHandle (UserHandle);
387 if (EFI_ERROR (Status)) {
388 return Status;
389 }
390
391 //
392 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
393 //
394 Prot = SmmFindProtocolInterface (UserHandle, Protocol, Interface);
395 if (Prot == NULL) {
396 return EFI_NOT_FOUND;
397 }
398
399 //
400 // Remove the protocol interface from the protocol
401 //
402 Status = EFI_NOT_FOUND;
403 Handle = (IHANDLE *)UserHandle;
404 Prot = SmmRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
405
406 if (Prot != NULL) {
407 //
408 // Remove the protocol interface from the handle
409 //
410 RemoveEntryList (&Prot->Link);
411
412 //
413 // Free the memory
414 //
415 Prot->Signature = 0;
416 FreePool (Prot);
417 Status = EFI_SUCCESS;
418 }
419
420 //
421 // If there are no more handlers for the handle, free the handle
422 //
423 if (IsListEmpty (&Handle->Protocols)) {
424 Handle->Signature = 0;
425 RemoveEntryList (&Handle->AllHandles);
426 FreePool (Handle);
427 }
428
429 return Status;
430}
431
443 IN EFI_HANDLE UserHandle,
444 IN EFI_GUID *Protocol
445 )
446{
447 EFI_STATUS Status;
448 PROTOCOL_ENTRY *ProtEntry;
449 PROTOCOL_INTERFACE *Prot;
450 IHANDLE *Handle;
451 LIST_ENTRY *Link;
452
453 Status = SmmValidateHandle (UserHandle);
454 if (EFI_ERROR (Status)) {
455 return NULL;
456 }
457
458 Handle = (IHANDLE *)UserHandle;
459
460 //
461 // Look at each protocol interface for a match
462 //
463 for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
464 Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
465 ProtEntry = Prot->Protocol;
466 if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {
467 return Prot;
468 }
469 }
470
471 return NULL;
472}
473
490EFIAPI
492 IN EFI_HANDLE UserHandle,
493 IN EFI_GUID *Protocol,
494 OUT VOID **Interface
495 )
496{
497 EFI_STATUS Status;
498 PROTOCOL_INTERFACE *Prot;
499
500 //
501 // Check for invalid Protocol
502 //
503 if (Protocol == NULL) {
504 return EFI_INVALID_PARAMETER;
505 }
506
507 //
508 // Check for invalid Interface
509 //
510 if (Interface == NULL) {
511 return EFI_INVALID_PARAMETER;
512 } else {
513 *Interface = NULL;
514 }
515
516 //
517 // Check for invalid UserHandle
518 //
519 Status = SmmValidateHandle (UserHandle);
520 if (EFI_ERROR (Status)) {
521 return Status;
522 }
523
524 //
525 // Look at each protocol interface for a match
526 //
527 Prot = SmmGetProtocolInterface (UserHandle, Protocol);
528 if (Prot == NULL) {
529 return EFI_UNSUPPORTED;
530 }
531
532 //
533 // This is the protocol interface entry for this protocol
534 //
535 *Interface = Prot->Interface;
536
537 return EFI_SUCCESS;
538}
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2884
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
PROTOCOL_INTERFACE * SmmFindProtocolInterface(IN IHANDLE *Handle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Handle.c:122
EFI_STATUS EFIAPI SmmUninstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Handle.c:366
EFI_STATUS EFIAPI SmmHandleProtocol(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface)
Definition: Handle.c:491
EFI_STATUS SmmValidateHandle(IN EFI_HANDLE UserHandle)
Definition: Handle.c:28
EFI_STATUS EFIAPI SmmInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
Definition: Handle.c:174
EFI_STATUS SmmInstallProtocolInterfaceNotify(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface, IN BOOLEAN Notify)
Definition: Handle.c:208
PROTOCOL_INTERFACE * SmmGetProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol)
Definition: Handle.c:442
PROTOCOL_ENTRY * SmmFindProtocolEntry(IN EFI_GUID *Protocol, IN BOOLEAN Create)
Definition: Handle.c:56
VOID SmmNotifyProtocol(IN PROTOCOL_INTERFACE *Prot)
Definition: Notify.c:18
PROTOCOL_INTERFACE * SmmRemoveInterfaceFromProtocol(IN IHANDLE *Handle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Notify.c:44
#define NULL
Definition: Base.h:319
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:660
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_INTERFACE_TYPE
Definition: UefiSpec.h:1199
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1203
Definition: Base.h:213
Definition: Handle.h:17
LIST_ENTRY AllHandles
All handles list of IHANDLE.
Definition: Handle.h:20
LIST_ENTRY Protocols
List of PROTOCOL_INTERFACE's for this handle.
Definition: Handle.h:22
LIST_ENTRY Notify
Registerd notification handlers.
Definition: Handle.h:46
LIST_ENTRY AllEntries
Link Entry inserted to mProtocolDatabase.
Definition: Handle.h:40
EFI_GUID ProtocolID
ID of the protocol.
Definition: Handle.h:42
LIST_ENTRY Protocols
All protocol interfaces.
Definition: Handle.h:44
LIST_ENTRY Link
Link on IHANDLE.Protocols.
Definition: Handle.h:58
IHANDLE * Handle
Back pointer.
Definition: Handle.h:60
PROTOCOL_ENTRY * Protocol
The protocol ID.
Definition: Handle.h:64
VOID * Interface
The interface value.
Definition: Handle.h:66
LIST_ENTRY ByProtocol
Link on PROTOCOL_ENTRY.Protocols.
Definition: Handle.h:62