2 Support functions for UEFI protocol notification infrastructure.
4 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
5 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "StandaloneMmCore.h"
13 Signal event for every protocol in protocol entry.
15 @param Prot Protocol interface
20 IN PROTOCOL_INTERFACE
*Prot
23 PROTOCOL_ENTRY
*ProtEntry
;
24 PROTOCOL_NOTIFY
*ProtNotify
;
27 ProtEntry
= Prot
->Protocol
;
28 for (Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
= Link
->ForwardLink
) {
29 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
30 ProtNotify
->Function (&ProtEntry
->ProtocolID
, Prot
->Interface
, Prot
->Handle
);
35 Removes Protocol from the protocol list (but not the handle list).
37 @param Handle The handle to remove protocol on.
38 @param Protocol GUID of the protocol to be moved
39 @param Interface The interface of the protocol
41 @return Protocol Entry
45 MmRemoveInterfaceFromProtocol (
47 IN EFI_GUID
*Protocol
,
51 PROTOCOL_INTERFACE
*Prot
;
52 PROTOCOL_NOTIFY
*ProtNotify
;
53 PROTOCOL_ENTRY
*ProtEntry
;
56 Prot
= MmFindProtocolInterface (Handle
, Protocol
, Interface
);
58 ProtEntry
= Prot
->Protocol
;
61 // If there's a protocol notify location pointing to this entry, back it up one
63 for (Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
= Link
->ForwardLink
) {
64 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
66 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
67 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
72 // Remove the protocol interface entry
74 RemoveEntryList (&Prot
->ByProtocol
);
81 Add a new protocol notification record for the request protocol.
83 @param Protocol The requested protocol to add the notify
85 @param Function Points to the notification function
86 @param Registration Returns the registration record
88 @retval EFI_SUCCESS Successfully returned the registration record
89 that has been added or unhooked
90 @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL
91 @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request
92 @retval EFI_NOT_FOUND If the registration is not found when Function == NULL
97 MmRegisterProtocolNotify (
98 IN CONST EFI_GUID
*Protocol
,
99 IN EFI_MM_NOTIFY_FN Function
,
100 OUT VOID
**Registration
103 PROTOCOL_ENTRY
*ProtEntry
;
104 PROTOCOL_NOTIFY
*ProtNotify
;
108 if ((Protocol
== NULL
) || (Registration
== NULL
)) {
109 return EFI_INVALID_PARAMETER
;
112 if (Function
== NULL
) {
114 // Get the protocol entry per Protocol
116 ProtEntry
= MmFindProtocolEntry ((EFI_GUID
*)Protocol
, FALSE
);
117 if (ProtEntry
!= NULL
) {
118 ProtNotify
= (PROTOCOL_NOTIFY
*)*Registration
;
119 for (Link
= ProtEntry
->Notify
.ForwardLink
;
120 Link
!= &ProtEntry
->Notify
;
121 Link
= Link
->ForwardLink
)
124 // Compare the notification record
126 if (ProtNotify
== (CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
))) {
128 // If Registration is an existing registration, then unhook it
130 ProtNotify
->Signature
= 0;
131 RemoveEntryList (&ProtNotify
->Link
);
132 FreePool (ProtNotify
);
139 // If the registration is not found
141 return EFI_NOT_FOUND
;
147 // Get the protocol entry to add the notification too
149 ProtEntry
= MmFindProtocolEntry ((EFI_GUID
*)Protocol
, TRUE
);
150 if (ProtEntry
!= NULL
) {
152 // Find whether notification already exist
154 for (Link
= ProtEntry
->Notify
.ForwardLink
;
155 Link
!= &ProtEntry
->Notify
;
156 Link
= Link
->ForwardLink
)
158 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
159 if (CompareGuid (&ProtNotify
->Protocol
->ProtocolID
, Protocol
) &&
160 (ProtNotify
->Function
== Function
))
163 // Notification already exist
165 *Registration
= ProtNotify
;
172 // Allocate a new notification record
174 ProtNotify
= AllocatePool (sizeof (PROTOCOL_NOTIFY
));
175 if (ProtNotify
!= NULL
) {
176 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
177 ProtNotify
->Protocol
= ProtEntry
;
178 ProtNotify
->Function
= Function
;
180 // Start at the ending
182 ProtNotify
->Position
= ProtEntry
->Protocols
.BackLink
;
184 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
189 // Done. If we have a protocol notify entry, then return it.
190 // Otherwise, we must have run out of resources trying to add one
192 Status
= EFI_OUT_OF_RESOURCES
;
193 if (ProtNotify
!= NULL
) {
194 *Registration
= ProtNotify
;
195 Status
= EFI_SUCCESS
;