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
);
59 ProtEntry
= Prot
->Protocol
;
62 // If there's a protocol notify location pointing to this entry, back it up one
64 for (Link
= ProtEntry
->Notify
.ForwardLink
; Link
!= &ProtEntry
->Notify
; Link
= Link
->ForwardLink
) {
65 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
67 if (ProtNotify
->Position
== &Prot
->ByProtocol
) {
68 ProtNotify
->Position
= Prot
->ByProtocol
.BackLink
;
73 // Remove the protocol interface entry
75 RemoveEntryList (&Prot
->ByProtocol
);
82 Add a new protocol notification record for the request protocol.
84 @param Protocol The requested protocol to add the notify
86 @param Function Points to the notification function
87 @param Registration Returns the registration record
89 @retval EFI_SUCCESS Successfully returned the registration record
90 that has been added or unhooked
91 @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL
92 @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request
93 @retval EFI_NOT_FOUND If the registration is not found when Function == NULL
98 MmRegisterProtocolNotify (
99 IN CONST EFI_GUID
*Protocol
,
100 IN EFI_MM_NOTIFY_FN Function
,
101 OUT VOID
**Registration
104 PROTOCOL_ENTRY
*ProtEntry
;
105 PROTOCOL_NOTIFY
*ProtNotify
;
109 if (Protocol
== NULL
|| Registration
== NULL
) {
110 return EFI_INVALID_PARAMETER
;
113 if (Function
== NULL
) {
115 // Get the protocol entry per Protocol
117 ProtEntry
= MmFindProtocolEntry ((EFI_GUID
*) Protocol
, FALSE
);
118 if (ProtEntry
!= NULL
) {
119 ProtNotify
= (PROTOCOL_NOTIFY
* )*Registration
;
120 for (Link
= ProtEntry
->Notify
.ForwardLink
;
121 Link
!= &ProtEntry
->Notify
;
122 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
);
138 // If the registration is not found
140 return EFI_NOT_FOUND
;
146 // Get the protocol entry to add the notification too
148 ProtEntry
= MmFindProtocolEntry ((EFI_GUID
*) Protocol
, TRUE
);
149 if (ProtEntry
!= NULL
) {
151 // Find whether notification already exist
153 for (Link
= ProtEntry
->Notify
.ForwardLink
;
154 Link
!= &ProtEntry
->Notify
;
155 Link
= Link
->ForwardLink
) {
157 ProtNotify
= CR (Link
, PROTOCOL_NOTIFY
, Link
, PROTOCOL_NOTIFY_SIGNATURE
);
158 if (CompareGuid (&ProtNotify
->Protocol
->ProtocolID
, Protocol
) &&
159 (ProtNotify
->Function
== Function
)) {
162 // Notification already exist
164 *Registration
= ProtNotify
;
171 // Allocate a new notification record
173 ProtNotify
= AllocatePool (sizeof (PROTOCOL_NOTIFY
));
174 if (ProtNotify
!= NULL
) {
175 ProtNotify
->Signature
= PROTOCOL_NOTIFY_SIGNATURE
;
176 ProtNotify
->Protocol
= ProtEntry
;
177 ProtNotify
->Function
= Function
;
179 // Start at the ending
181 ProtNotify
->Position
= ProtEntry
->Protocols
.BackLink
;
183 InsertTailList (&ProtEntry
->Notify
, &ProtNotify
->Link
);
188 // Done. If we have a protocol notify entry, then return it.
189 // Otherwise, we must have run out of resources trying to add one
191 Status
= EFI_OUT_OF_RESOURCES
;
192 if (ProtNotify
!= NULL
) {
193 *Registration
= ProtNotify
;
194 Status
= EFI_SUCCESS
;