OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcDriverConnectionLib.c
Go to the documentation of this file.
1
15#include <Library/MemoryAllocationLib.h>
16#include <Library/DebugLib.h>
18#include <Library/UefiBootServicesTableLib.h>
19#include <Protocol/PlatformDriverOverride.h>
20
21//
22// NULL-terminated list of driver handles that will be served by EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
23//
24STATIC EFI_HANDLE *mPriorityDrivers;
25
26//
27// Saved original EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.GetDriver when doing override.
28//
29STATIC EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER mOrgPlatformGetDriver;
30
31STATIC
32EFI_STATUS
33EFIAPI
35 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
36 IN EFI_HANDLE ControllerHandle,
37 IN OUT EFI_HANDLE *DriverImageHandle
38 )
39{
40 EFI_HANDLE *HandlePtr;
41 BOOLEAN FoundLast;
42
43 if (ControllerHandle == NULL) {
44 return EFI_INVALID_PARAMETER;
45 }
46
47 //
48 // We have no custom overrides.
49 //
50 if ((mPriorityDrivers == NULL) || (mPriorityDrivers[0] == NULL)) {
51 //
52 // Forward request to the original driver if we have it.
53 //
54 if (mOrgPlatformGetDriver != NULL) {
55 return mOrgPlatformGetDriver (This, ControllerHandle, DriverImageHandle);
56 }
57
58 //
59 // Report not found for the first request.
60 //
61 if (*DriverImageHandle == NULL) {
62 return EFI_NOT_FOUND;
63 }
64
65 //
66 // Report invalid parameter for the handle we could not have returned.
67 //
68 return EFI_INVALID_PARAMETER;
69 }
70
71 //
72 // Handle first driver in the overrides.
73 //
74 if (*DriverImageHandle == NULL) {
75 *DriverImageHandle = mPriorityDrivers[0];
76 return EFI_SUCCESS;
77 }
78
79 //
80 // Otherwise lookup the current driver in the list.
81 //
82
83 FoundLast = FALSE;
84
85 for (HandlePtr = &mPriorityDrivers[0]; HandlePtr[0] != NULL; ++HandlePtr) {
86 //
87 // Found driver in the list, return next one.
88 //
89 if (HandlePtr[0] == *DriverImageHandle) {
90 *DriverImageHandle = HandlePtr[1];
91 //
92 // Next driver is not last, return it.
93 //
94 if (*DriverImageHandle != NULL) {
95 return EFI_SUCCESS;
96 }
97
98 //
99 // Next driver is last, exit the loop.
100 //
101 FoundLast = TRUE;
102 break;
103 }
104 }
105
106 //
107 // We have no original protocol.
108 //
109 if (mOrgPlatformGetDriver == NULL) {
110 //
111 // Finalise the list by reporting not found.
112 //
113 if (FoundLast) {
114 return EFI_NOT_FOUND;
115 }
116
117 //
118 // Error as the passed handle is not valid.
119 //
120 return EFI_INVALID_PARAMETER;
121 }
122
123 //
124 // Forward the call to the original driver:
125 // - if FoundLast, then it is starting to iterating original list and DriverImageHandle
126 // is nulled above.
127 // - otherwise, then it is iterating the original list or is invalid.
128 //
129 return mOrgPlatformGetDriver (This, ControllerHandle, DriverImageHandle);
130}
131
132STATIC
133EFI_STATUS
134EFIAPI
136 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
137 IN EFI_HANDLE ControllerHandle,
138 IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath
139 )
140{
141 return EFI_UNSUPPORTED;
142}
143
144STATIC
145EFI_STATUS
146EFIAPI
148 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
149 IN EFI_HANDLE ControllerHandle,
150 IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,
151 IN EFI_HANDLE DriverImageHandle
152 )
153{
154 return EFI_UNSUPPORTED;
155}
156
157STATIC
158EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
164
165EFI_STATUS
167 IN EFI_HANDLE *PriorityDrivers
168 )
169{
170 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
171 EFI_STATUS Status;
172 EFI_HANDLE NewHandle;
173
174 ASSERT (PriorityDrivers != NULL);
175
176 mPriorityDrivers = PriorityDrivers;
177 Status = gBS->LocateProtocol (
178 &gEfiPlatformDriverOverrideProtocolGuid,
179 NULL,
180 (VOID **)&PlatformDriverOverride
181 );
182
183 if (!EFI_ERROR (Status)) {
184 mOrgPlatformGetDriver = PlatformDriverOverride->GetDriver;
185 PlatformDriverOverride->GetDriver = OcPlatformGetDriver;
186 return Status;
187 }
188
189 NewHandle = NULL;
190 return gBS->InstallMultipleProtocolInterfaces (
191 &NewHandle,
192 &gEfiPlatformDriverOverrideProtocolGuid,
194 NULL
195 );
196}
197
198EFI_STATUS
200 VOID
201 )
202{
203 EFI_STATUS Status;
204 UINTN HandleCount;
205 EFI_HANDLE *HandleBuffer;
206 UINTN DeviceIndex;
207 UINTN HandleIndex;
208 UINTN ProtocolIndex;
209 UINTN InfoIndex;
210 EFI_GUID **ProtocolGuids;
211 UINTN ProtocolCount;
212 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *ProtocolInfos;
213 UINTN ProtocolInfoCount;
214 BOOLEAN Connect;
215
216 //
217 // We locate only handles with device paths as connecting other handles
218 // will crash APTIO IV.
219 //
220 Status = gBS->LocateHandleBuffer (
221 ByProtocol,
223 NULL,
224 &HandleCount,
225 &HandleBuffer
226 );
227
228 if (EFI_ERROR (Status)) {
229 return Status;
230 }
231
232 for (DeviceIndex = 0; DeviceIndex < HandleCount; ++DeviceIndex) {
233 //
234 // Only connect parent handles as we connect recursively.
235 // This improves the performance by more than 30 seconds
236 // with drives installed into Marvell SATA controllers on APTIO IV.
237 //
238 Connect = TRUE;
239 for (HandleIndex = 0; HandleIndex < HandleCount && Connect; ++HandleIndex) {
240 //
241 // Retrieve the list of all the protocols on each handle
242 //
243 Status = gBS->ProtocolsPerHandle (
244 HandleBuffer[HandleIndex],
245 &ProtocolGuids,
246 &ProtocolCount
247 );
248
249 if (EFI_ERROR (Status)) {
250 continue;
251 }
252
253 for (ProtocolIndex = 0; ProtocolIndex < ProtocolCount && Connect; ++ProtocolIndex) {
254 //
255 // Retrieve the list of agents that have opened each protocol
256 //
257 Status = gBS->OpenProtocolInformation (
258 HandleBuffer[HandleIndex],
259 ProtocolGuids[ProtocolIndex],
260 &ProtocolInfos,
261 &ProtocolInfoCount
262 );
263
264 if (!EFI_ERROR (Status)) {
265 for (InfoIndex = 0; InfoIndex < ProtocolInfoCount && Connect; ++InfoIndex) {
266 if ( (ProtocolInfos[InfoIndex].ControllerHandle == HandleBuffer[DeviceIndex])
267 && ((ProtocolInfos[InfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER))
268 {
269 Connect = FALSE;
270 }
271 }
272
273 FreePool (ProtocolInfos);
274 }
275 }
276
277 FreePool (ProtocolGuids);
278 }
279
280 if (Connect) {
281 //
282 // We connect all handles to all drivers as otherwise fs drivers may not be seen.
283 //
284 gBS->ConnectController (HandleBuffer[DeviceIndex], NULL, NULL, TRUE);
285 }
286 }
287
288 FreePool (HandleBuffer);
289
290 return EFI_SUCCESS;
291}
EFI_BOOT_SERVICES * gBS
EFI_STATUS OcRegisterDriversToHighestPriority(IN EFI_HANDLE *PriorityDrivers)
STATIC EFI_STATUS EFIAPI OcPlatformDriverLoaded(IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath, IN EFI_HANDLE DriverImageHandle)
EFI_STATUS OcConnectDrivers(VOID)
STATIC EFI_HANDLE * mPriorityDrivers
STATIC EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL mOcPlatformDriverOverrideProtocol
STATIC EFI_STATUS EFIAPI OcPlatformGetDriverPath(IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath)
STATIC EFI_PLATFORM_DRIVER_OVERRIDE_GET_DRIVER mOrgPlatformGetDriver
STATIC EFI_STATUS EFIAPI OcPlatformGetDriver(IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN OUT EFI_HANDLE *DriverImageHandle)
EFI_GUID gEfiDevicePathProtocolGuid
#define ASSERT(x)
Definition coder.h:55