StandaloneMmPkg: Add CPU driver suitable for ARM Platforms.
[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
6 This program and the accompanying materials are licensed and made available\r
7 under the terms and conditions of the BSD License which accompanies this\r
8 distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "StandaloneMmCore.h"\r
17\r
18/**\r
19 Signal event for every protocol in protocol entry.\r
20\r
21 @param Prot Protocol interface\r
22\r
23**/\r
24VOID\r
25MmNotifyProtocol (\r
26 IN PROTOCOL_INTERFACE *Prot\r
27 )\r
28{\r
29 PROTOCOL_ENTRY *ProtEntry;\r
30 PROTOCOL_NOTIFY *ProtNotify;\r
31 LIST_ENTRY *Link;\r
32\r
33 ProtEntry = Prot->Protocol;\r
34 for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {\r
35 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
36 ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);\r
37 }\r
38}\r
39\r
40/**\r
41 Removes Protocol from the protocol list (but not the handle list).\r
42\r
43 @param Handle The handle to remove protocol on.\r
44 @param Protocol GUID of the protocol to be moved\r
45 @param Interface The interface of the protocol\r
46\r
47 @return Protocol Entry\r
48\r
49**/\r
50PROTOCOL_INTERFACE *\r
51MmRemoveInterfaceFromProtocol (\r
52 IN IHANDLE *Handle,\r
53 IN EFI_GUID *Protocol,\r
54 IN VOID *Interface\r
55 )\r
56{\r
57 PROTOCOL_INTERFACE *Prot;\r
58 PROTOCOL_NOTIFY *ProtNotify;\r
59 PROTOCOL_ENTRY *ProtEntry;\r
60 LIST_ENTRY *Link;\r
61\r
62 Prot = MmFindProtocolInterface (Handle, Protocol, Interface);\r
63 if (Prot != NULL) {\r
64\r
65 ProtEntry = Prot->Protocol;\r
66\r
67 //\r
68 // If there's a protocol notify location pointing to this entry, back it up one\r
69 //\r
70 for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
71 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
72\r
73 if (ProtNotify->Position == &Prot->ByProtocol) {\r
74 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
75 }\r
76 }\r
77\r
78 //\r
79 // Remove the protocol interface entry\r
80 //\r
81 RemoveEntryList (&Prot->ByProtocol);\r
82 }\r
83\r
84 return Prot;\r
85}\r
86\r
87/**\r
88 Add a new protocol notification record for the request protocol.\r
89\r
90 @param Protocol The requested protocol to add the notify\r
91 registration\r
92 @param Function Points to the notification function\r
93 @param Registration Returns the registration record\r
94\r
95 @retval EFI_SUCCESS Successfully returned the registration record\r
96 that has been added or unhooked\r
97 @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL\r
98 @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request\r
99 @retval EFI_NOT_FOUND If the registration is not found when Function == NULL\r
100\r
101**/\r
102EFI_STATUS\r
103EFIAPI\r
104MmRegisterProtocolNotify (\r
105 IN CONST EFI_GUID *Protocol,\r
106 IN EFI_MM_NOTIFY_FN Function,\r
107 OUT VOID **Registration\r
108 )\r
109{\r
110 PROTOCOL_ENTRY *ProtEntry;\r
111 PROTOCOL_NOTIFY *ProtNotify;\r
112 LIST_ENTRY *Link;\r
113 EFI_STATUS Status;\r
114\r
115 if (Protocol == NULL || Registration == NULL) {\r
116 return EFI_INVALID_PARAMETER;\r
117 }\r
118\r
119 if (Function == NULL) {\r
120 //\r
121 // Get the protocol entry per Protocol\r
122 //\r
123 ProtEntry = MmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE);\r
124 if (ProtEntry != NULL) {\r
125 ProtNotify = (PROTOCOL_NOTIFY * )*Registration;\r
126 for (Link = ProtEntry->Notify.ForwardLink;\r
127 Link != &ProtEntry->Notify;\r
128 Link = Link->ForwardLink) {\r
129 //\r
130 // Compare the notification record\r
131 //\r
132 if (ProtNotify == (CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))) {\r
133 //\r
134 // If Registration is an existing registration, then unhook it\r
135 //\r
136 ProtNotify->Signature = 0;\r
137 RemoveEntryList (&ProtNotify->Link);\r
138 FreePool (ProtNotify);\r
139 return EFI_SUCCESS;\r
140 }\r
141 }\r
142 }\r
143 //\r
144 // If the registration is not found\r
145 //\r
146 return EFI_NOT_FOUND;\r
147 }\r
148\r
149 ProtNotify = NULL;\r
150\r
151 //\r
152 // Get the protocol entry to add the notification too\r
153 //\r
154 ProtEntry = MmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);\r
155 if (ProtEntry != NULL) {\r
156 //\r
157 // Find whether notification already exist\r
158 //\r
159 for (Link = ProtEntry->Notify.ForwardLink;\r
160 Link != &ProtEntry->Notify;\r
161 Link = Link->ForwardLink) {\r
162\r
163 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
164 if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) &&\r
165 (ProtNotify->Function == Function)) {\r
166\r
167 //\r
168 // Notification already exist\r
169 //\r
170 *Registration = ProtNotify;\r
171\r
172 return EFI_SUCCESS;\r
173 }\r
174 }\r
175\r
176 //\r
177 // Allocate a new notification record\r
178 //\r
179 ProtNotify = AllocatePool (sizeof (PROTOCOL_NOTIFY));\r
180 if (ProtNotify != NULL) {\r
181 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
182 ProtNotify->Protocol = ProtEntry;\r
183 ProtNotify->Function = Function;\r
184 //\r
185 // Start at the ending\r
186 //\r
187 ProtNotify->Position = ProtEntry->Protocols.BackLink;\r
188\r
189 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
190 }\r
191 }\r
192\r
193 //\r
194 // Done. If we have a protocol notify entry, then return it.\r
195 // Otherwise, we must have run out of resources trying to add one\r
196 //\r
197 Status = EFI_OUT_OF_RESOURCES;\r
198 if (ProtNotify != NULL) {\r
199 *Registration = ProtNotify;\r
200 Status = EFI_SUCCESS;\r
201 }\r
202 return Status;\r
203}\r