]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Hand/Notify.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Hand / Notify.c
CommitLineData
23c98c94 1/** @file\r
6c857d66 2 Support functions for UEFI protocol notification infrastructure.\r
28a00297 3\r
cd5ebaa0 4Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
82f3edf2 5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
28a00297 7\r
504214c4 8**/\r
28a00297 9\r
9c4ac31c 10#include "DxeMain.h"\r
ec90508b 11#include "Handle.h"\r
82f3edf2 12#include "Event.h"\r
28a00297 13\r
162ed594 14/**\r
28a00297 15 Signal event for every protocol in protocol entry.\r
16\r
162ed594 17 @param ProtEntry Protocol entry\r
28a00297 18\r
162ed594 19**/\r
20VOID\r
21CoreNotifyProtocolEntry (\r
1436aea4 22 IN PROTOCOL_ENTRY *ProtEntry\r
162ed594 23 )\r
28a00297 24{\r
1436aea4
MK
25 PROTOCOL_NOTIFY *ProtNotify;\r
26 LIST_ENTRY *Link;\r
28a00297 27\r
28 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
29\r
1436aea4
MK
30 for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
31 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
28a00297 32 CoreSignalEvent (ProtNotify->Event);\r
33 }\r
34}\r
35\r
162ed594 36/**\r
37 Removes Protocol from the protocol list (but not the handle list).\r
38\r
022c6d45 39 @param Handle The handle to remove protocol on.\r
40 @param Protocol GUID of the protocol to be moved\r
41 @param Interface The interface of the protocol\r
162ed594 42\r
43 @return Protocol Entry\r
44\r
45**/\r
28a00297 46PROTOCOL_INTERFACE *\r
47CoreRemoveInterfaceFromProtocol (\r
1436aea4
MK
48 IN IHANDLE *Handle,\r
49 IN EFI_GUID *Protocol,\r
50 IN VOID *Interface\r
28a00297 51 )\r
28a00297 52{\r
53 PROTOCOL_INTERFACE *Prot;\r
54 PROTOCOL_NOTIFY *ProtNotify;\r
55 PROTOCOL_ENTRY *ProtEntry;\r
56 LIST_ENTRY *Link;\r
57\r
58 ASSERT_LOCKED (&gProtocolDatabaseLock);\r
59\r
60 Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);\r
61 if (Prot != NULL) {\r
28a00297 62 ProtEntry = Prot->Protocol;\r
63\r
64 //\r
65 // If there's a protocol notify location pointing to this entry, back it up one\r
66 //\r
1436aea4
MK
67 for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {\r
68 ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);\r
28a00297 69\r
70 if (ProtNotify->Position == &Prot->ByProtocol) {\r
71 ProtNotify->Position = Prot->ByProtocol.BackLink;\r
72 }\r
73 }\r
74\r
75 //\r
76 // Remove the protocol interface entry\r
77 //\r
28a00297 78 RemoveEntryList (&Prot->ByProtocol);\r
79 }\r
80\r
81 return Prot;\r
82}\r
83\r
162ed594 84/**\r
85 Add a new protocol notification record for the request protocol.\r
86\r
022c6d45 87 @param Protocol The requested protocol to add the notify\r
88 registration\r
89 @param Event The event to signal\r
90 @param Registration Returns the registration record\r
162ed594 91\r
022c6d45 92 @retval EFI_INVALID_PARAMETER Invalid parameter\r
93 @retval EFI_SUCCESS Successfully returned the registration record\r
162ed594 94 that has been added\r
95\r
96**/\r
28a00297 97EFI_STATUS\r
98EFIAPI\r
99CoreRegisterProtocolNotify (\r
1436aea4
MK
100 IN EFI_GUID *Protocol,\r
101 IN EFI_EVENT Event,\r
102 OUT VOID **Registration\r
28a00297 103 )\r
28a00297 104{\r
1436aea4
MK
105 PROTOCOL_ENTRY *ProtEntry;\r
106 PROTOCOL_NOTIFY *ProtNotify;\r
107 EFI_STATUS Status;\r
022c6d45 108\r
1436aea4 109 if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {\r
28a00297 110 return EFI_INVALID_PARAMETER;\r
111 }\r
112\r
113 CoreAcquireProtocolLock ();\r
114\r
115 ProtNotify = NULL;\r
022c6d45 116\r
28a00297 117 //\r
118 // Get the protocol entry to add the notification too\r
119 //\r
120\r
121 ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);\r
122 if (ProtEntry != NULL) {\r
28a00297 123 //\r
124 // Allocate a new notification record\r
125 //\r
1436aea4 126 ProtNotify = AllocatePool (sizeof (PROTOCOL_NOTIFY));\r
28a00297 127 if (ProtNotify != NULL) {\r
82f3edf2 128 ((IEVENT *)Event)->ExFlag |= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION;\r
1436aea4
MK
129 ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;\r
130 ProtNotify->Protocol = ProtEntry;\r
131 ProtNotify->Event = Event;\r
28a00297 132 //\r
133 // start at the begining\r
134 //\r
022c6d45 135 ProtNotify->Position = &ProtEntry->Protocols;\r
28a00297 136\r
137 InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);\r
138 }\r
139 }\r
140\r
141 CoreReleaseProtocolLock ();\r
142\r
143 //\r
144 // Done. If we have a protocol notify entry, then return it.\r
145 // Otherwise, we must have run out of resources trying to add one\r
146 //\r
147\r
148 Status = EFI_OUT_OF_RESOURCES;\r
149 if (ProtNotify != NULL) {\r
150 *Registration = ProtNotify;\r
1436aea4 151 Status = EFI_SUCCESS;\r
28a00297 152 }\r
153\r
154 return Status;\r
155}\r
156\r
162ed594 157/**\r
158 Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.\r
159\r
022c6d45 160 @param UserHandle Handle on which the interface is to be\r
161 reinstalled\r
162 @param Protocol The numeric ID of the interface\r
163 @param OldInterface A pointer to the old interface\r
164 @param NewInterface A pointer to the new interface\r
162ed594 165\r
166 @retval EFI_SUCCESS The protocol interface was installed\r
167 @retval EFI_NOT_FOUND The OldInterface on the handle was not found\r
168 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value\r
169\r
170**/\r
28a00297 171EFI_STATUS\r
172EFIAPI\r
173CoreReinstallProtocolInterface (\r
1436aea4
MK
174 IN EFI_HANDLE UserHandle,\r
175 IN EFI_GUID *Protocol,\r
176 IN VOID *OldInterface,\r
177 IN VOID *NewInterface\r
28a00297 178 )\r
28a00297 179{\r
1436aea4
MK
180 EFI_STATUS Status;\r
181 IHANDLE *Handle;\r
182 PROTOCOL_INTERFACE *Prot;\r
183 PROTOCOL_ENTRY *ProtEntry;\r
28a00297 184\r
28a00297 185 if (Protocol == NULL) {\r
186 return EFI_INVALID_PARAMETER;\r
187 }\r
188\r
28a00297 189 //\r
190 // Lock the protocol database\r
191 //\r
192 CoreAcquireProtocolLock ();\r
193\r
a7fcab7a
HM
194 Status = CoreValidateHandle (UserHandle);\r
195 if (EFI_ERROR (Status)) {\r
196 goto Done;\r
197 }\r
198\r
1436aea4 199 Handle = (IHANDLE *)UserHandle;\r
28a00297 200 //\r
201 // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
202 //\r
203 Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);\r
204 if (Prot == NULL) {\r
6c857d66 205 Status = EFI_NOT_FOUND;\r
206 goto Done;\r
28a00297 207 }\r
208\r
209 //\r
210 // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled\r
211 //\r
212 Status = CoreDisconnectControllersUsingProtocolInterface (\r
213 UserHandle,\r
214 Prot\r
215 );\r
216 if (EFI_ERROR (Status)) {\r
217 //\r
218 // One or more drivers refused to release, so return the error\r
219 //\r
6c857d66 220 goto Done;\r
28a00297 221 }\r
222\r
223 //\r
224 // Remove the protocol interface from the protocol\r
225 //\r
226 Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);\r
227\r
228 if (Prot == NULL) {\r
6c857d66 229 Status = EFI_NOT_FOUND;\r
230 goto Done;\r
28a00297 231 }\r
232\r
233 ProtEntry = Prot->Protocol;\r
234\r
235 //\r
236 // Update the interface on the protocol\r
237 //\r
238 Prot->Interface = NewInterface;\r
239\r
240 //\r
241 // Add this protocol interface to the tail of the\r
242 // protocol entry\r
243 //\r
244 InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);\r
245\r
246 //\r
247 // Update the Key to show that the handle has been created/modified\r
248 //\r
249 gHandleDatabaseKey++;\r
250 Handle->Key = gHandleDatabaseKey;\r
251\r
252 //\r
253 // Release the lock and connect all drivers to UserHandle\r
254 //\r
255 CoreReleaseProtocolLock ();\r
6c857d66 256 //\r
257 // Return code is ignored on purpose.\r
258 //\r
259 CoreConnectController (\r
260 UserHandle,\r
261 NULL,\r
262 NULL,\r
263 TRUE\r
264 );\r
28a00297 265 CoreAcquireProtocolLock ();\r
022c6d45 266\r
28a00297 267 //\r
268 // Notify the notification list for this protocol\r
269 //\r
270 CoreNotifyProtocolEntry (ProtEntry);\r
271\r
6c857d66 272 Status = EFI_SUCCESS;\r
273\r
274Done:\r
fa3c419f 275 CoreReleaseProtocolLock ();\r
276\r
6c857d66 277 return Status;\r
28a00297 278}\r