]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Core/Notify.c
Revert "OvmfPkg/PlatformPei: fix MTRR for low-RAM sizes that have many bits clear"
[mirror_edk2.git] / StandaloneMmPkg / Core / Notify.c
CommitLineData
6b46d772
SV
1/** @file\r
2 Support functions for UEFI protocol notification infrastructure.\r
3\r
4 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
5 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
86094561 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
6b46d772
SV
7\r
8**/\r
9\r
10#include "StandaloneMmCore.h"\r
11\r
12/**\r
13 Signal event for every protocol in protocol entry.\r
14\r
15 @param Prot Protocol interface\r
16\r
17**/\r
18VOID\r
19MmNotifyProtocol (\r
20 IN PROTOCOL_INTERFACE *Prot\r
21 )\r
22{\r
23 PROTOCOL_ENTRY *ProtEntry;\r
24 PROTOCOL_NOTIFY *ProtNotify;\r
25 LIST_ENTRY *Link;\r
26\r
27 ProtEntry = Prot->Protocol;\r
28 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
29 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
30 ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);\r
31 }\r
32}\r
33\r
34/**\r
35 Removes Protocol from the protocol list (but not the handle list).\r
36\r
37 @param Handle The handle to remove protocol on.\r
38 @param Protocol GUID of the protocol to be moved\r
39 @param Interface The interface of the protocol\r
40\r
41 @return Protocol Entry\r
42\r
43**/\r
44PROTOCOL_INTERFACE *\r
45MmRemoveInterfaceFromProtocol (\r
46 IN IHANDLE *Handle,\r
47 IN EFI_GUID *Protocol,\r
48 IN VOID *Interface\r
49 )\r
50{\r
51 PROTOCOL_INTERFACE *Prot;\r
52 PROTOCOL_NOTIFY *ProtNotify;\r
53 PROTOCOL_ENTRY *ProtEntry;\r
54 LIST_ENTRY *Link;\r
55\r
56 Prot = MmFindProtocolInterface (Handle, Protocol, Interface);\r
57 if (Prot != NULL) {\r
58\r
59 ProtEntry = Prot->Protocol;\r
60\r
61 //\r
62 // If there's a protocol notify location pointing to this entry, back it up one\r
63 //\r
64 for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
65 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
66\r
67 if (ProtNotify->Position == &Prot->ByProtocol) {\r
68 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
69 }\r
70 }\r
71\r
72 //\r
73 // Remove the protocol interface entry\r
74 //\r
75 RemoveEntryList (&Prot->ByProtocol);\r
76 }\r
77\r
78 return Prot;\r
79}\r
80\r
81/**\r
82 Add a new protocol notification record for the request protocol.\r
83\r
84 @param Protocol The requested protocol to add the notify\r
85 registration\r
86 @param Function Points to the notification function\r
87 @param Registration Returns the registration record\r
88\r
89 @retval EFI_SUCCESS Successfully returned the registration record\r
90 that has been added or unhooked\r
91 @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL\r
92 @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request\r
93 @retval EFI_NOT_FOUND If the registration is not found when Function == NULL\r
94\r
95**/\r
96EFI_STATUS\r
97EFIAPI\r
98MmRegisterProtocolNotify (\r
99 IN CONST EFI_GUID *Protocol,\r
100 IN EFI_MM_NOTIFY_FN Function,\r
101 OUT VOID **Registration\r
102 )\r
103{\r
104 PROTOCOL_ENTRY *ProtEntry;\r
105 PROTOCOL_NOTIFY *ProtNotify;\r
106 LIST_ENTRY *Link;\r
107 EFI_STATUS Status;\r
108\r
109 if (Protocol == NULL || Registration == NULL) {\r
110 return EFI_INVALID_PARAMETER;\r
111 }\r
112\r
113 if (Function == NULL) {\r
114 //\r
115 // Get the protocol entry per Protocol\r
116 //\r
117 ProtEntry = MmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);\r
118 if (ProtEntry != NULL) {\r
119 ProtNotify = (PROTOCOL_NOTIFY * )*Registration;\r
120 for (Link = ProtEntry->Notify.ForwardLink;\r
121 Link != &ProtEntry->Notify;\r
122 Link = Link->ForwardLink) {\r
123 //\r
124 // Compare the notification record\r
125 //\r
126 if (ProtNotify == (CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))) {\r
127 //\r
128 // If Registration is an existing registration, then unhook it\r
129 //\r
130 ProtNotify->Signature = 0;\r
131 RemoveEntryList (&ProtNotify->Link);\r
132 FreePool (ProtNotify);\r
133 return EFI_SUCCESS;\r
134 }\r
135 }\r
136 }\r
137 //\r
138 // If the registration is not found\r
139 //\r
140 return EFI_NOT_FOUND;\r
141 }\r
142\r
143 ProtNotify = NULL;\r
144\r
145 //\r
146 // Get the protocol entry to add the notification too\r
147 //\r
148 ProtEntry = MmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);\r
149 if (ProtEntry != NULL) {\r
150 //\r
151 // Find whether notification already exist\r
152 //\r
153 for (Link = ProtEntry->Notify.ForwardLink;\r
154 Link != &ProtEntry->Notify;\r
155 Link = Link->ForwardLink) {\r
156\r
157 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
158 if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&\r
159 (ProtNotify->Function == Function)) {\r
160\r
161 //\r
162 // Notification already exist\r
163 //\r
164 *Registration = ProtNotify;\r
165\r
166 return EFI_SUCCESS;\r
167 }\r
168 }\r
169\r
170 //\r
171 // Allocate a new notification record\r
172 //\r
173 ProtNotify = AllocatePool (sizeof (PROTOCOL_NOTIFY));\r
174 if (ProtNotify != NULL) {\r
175 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
176 ProtNotify->Protocol = ProtEntry;\r
177 ProtNotify->Function = Function;\r
178 //\r
179 // Start at the ending\r
180 //\r
181 ProtNotify->Position = ProtEntry->Protocols.BackLink;\r
182\r
183 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
184 }\r
185 }\r
186\r
187 //\r
188 // Done. If we have a protocol notify entry, then return it.\r
189 // Otherwise, we must have run out of resources trying to add one\r
190 //\r
191 Status = EFI_OUT_OF_RESOURCES;\r
192 if (ProtNotify != NULL) {\r
193 *Registration = ProtNotify;\r
194 Status = EFI_SUCCESS;\r
195 }\r
196 return Status;\r
197}\r