OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
BdsConnect.c
Go to the documentation of this file.
1
15#include <IndustryStandard/Pci.h>
16
17#include <Library/DebugLib.h>
18#include <Library/DevicePathLib.h>
19#include <Library/DuetBdsLib.h>
20#include <Library/MemoryAllocationLib.h>
21#include <Library/UefiBootServicesTableLib.h>
22#include <Library/DxeServicesTableLib.h>
23#include <Library/UefiLib.h>
24
25#include <Protocol/PciIo.h>
26
34VOID
35EFIAPI
37 VOID
38 )
39{
40 //
41 // Connect the platform console first
42 //
44
45 //
46 // Generic way to connect all the drivers
47 //
49
50 //
51 // Here we have the assumption that we have already had
52 // platform default console
53 //
55}
56
64VOID
66 VOID
67 )
68{
69 //
70 // Most generic way to connect all the drivers
71 //
74}
75
92EFI_STATUS
93EFIAPI
95 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
96 )
97{
98 EFI_STATUS Status;
99 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
100 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
101 EFI_DEVICE_PATH_PROTOCOL *Instance;
102 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
103 EFI_DEVICE_PATH_PROTOCOL *Next;
104 EFI_HANDLE Handle;
105 EFI_HANDLE PreviousHandle;
106 UINTN Size;
107 EFI_TPL CurrentTpl;
108
109 if (DevicePathToConnect == NULL) {
110 return EFI_SUCCESS;
111 }
112
113 CurrentTpl = EfiGetCurrentTpl ();
114
115 DevicePath = DuplicateDevicePath (DevicePathToConnect);
116 if (DevicePath == NULL) {
117 return EFI_OUT_OF_RESOURCES;
118 }
119
120 CopyOfDevicePath = DevicePath;
121
122 do {
123 //
124 // The outer loop handles multi instance device paths.
125 // Only console variables contain multiple instance device paths.
126 //
127 // After this call DevicePath points to the next Instance
128 //
129 Instance = GetNextDevicePathInstance (&DevicePath, &Size);
130 if (Instance == NULL) {
131 FreePool (CopyOfDevicePath);
132 return EFI_OUT_OF_RESOURCES;
133 }
134
135 Next = Instance;
136 while (!IsDevicePathEndType (Next)) {
137 Next = NextDevicePathNode (Next);
138 }
139
140 SetDevicePathEndNode (Next);
141
142 //
143 // Start the real work of connect with RemainingDevicePath
144 //
145 PreviousHandle = NULL;
146 do {
147 //
148 // Find the handle that best matches the Device Path. If it is only a
149 // partial match the remaining part of the device path is returned in
150 // RemainingDevicePath.
151 //
152 RemainingDevicePath = Instance;
153 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);
154
155 if (!EFI_ERROR (Status)) {
156 if (Handle == PreviousHandle) {
157 //
158 // If no forward progress is made try invoking the Dispatcher.
159 // A new FV may have been added to the system an new drivers
160 // may now be found.
161 // Status == EFI_SUCCESS means a driver was dispatched
162 // Status == EFI_NOT_FOUND means no new drivers were dispatched
163 //
164 if (CurrentTpl == TPL_APPLICATION) {
165 //
166 // Dispatch calls LoadImage/StartImage which cannot run at TPL > TPL_APPLICATION
167 //
168 Status = gDS->Dispatch ();
169 } else {
170 //
171 // Always return EFI_NOT_FOUND here
172 // to prevent dead loop when control handle is found but connection failded case
173 //
174 Status = EFI_NOT_FOUND;
175 }
176 }
177
178 if (!EFI_ERROR (Status)) {
179 PreviousHandle = Handle;
180 //
181 // Connect all drivers that apply to Handle and RemainingDevicePath,
182 // the Recursive flag is FALSE so only one level will be expanded.
183 //
184 // Do not check the connect status here, if the connect controller fail,
185 // then still give the chance to do dispatch, because partial
186 // RemainingDevicepath may be in the new FV
187 //
188 // 1. If the connect fail, RemainingDevicepath and handle will not
189 // change, so next time will do the dispatch, then dispatch's status
190 // will take effect
191 // 2. If the connect success, the RemainingDevicepath and handle will
192 // change, then avoid the dispatch, we have chance to continue the
193 // next connection
194 //
195 gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
196 }
197 }
198
199 //
200 // Loop until RemainingDevicePath is an empty device path
201 //
202 } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
203 } while (DevicePath != NULL);
204
205 if (CopyOfDevicePath != NULL) {
206 FreePool (CopyOfDevicePath);
207 }
208
209 //
210 // All handle with DevicePath exists in the handle database
211 //
212 return Status;
213}
214
226EFI_STATUS
227EFIAPI
229 VOID
230 )
231{
232 EFI_STATUS Status;
233 UINTN HandleCount;
234 EFI_HANDLE *HandleBuffer;
235 UINTN Index;
236
237 Status = gBS->LocateHandleBuffer (
238 AllHandles,
239 NULL,
240 NULL,
241 &HandleCount,
242 &HandleBuffer
243 );
244 if (EFI_ERROR (Status)) {
245 return Status;
246 }
247
248 for (Index = 0; Index < HandleCount; Index++) {
249 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
250 }
251
252 if (HandleBuffer != NULL) {
253 FreePool (HandleBuffer);
254 }
255
256 return EFI_SUCCESS;
257}
258
270EFI_STATUS
271EFIAPI
273 VOID
274 )
275{
276 EFI_STATUS Status;
277 UINTN HandleCount;
278 EFI_HANDLE *HandleBuffer;
279 UINTN Index;
280
281 //
282 // Disconnect all
283 //
284 Status = gBS->LocateHandleBuffer (
285 AllHandles,
286 NULL,
287 NULL,
288 &HandleCount,
289 &HandleBuffer
290 );
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294
295 for (Index = 0; Index < HandleCount; Index++) {
296 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
297 }
298
299 if (HandleBuffer != NULL) {
300 FreePool (HandleBuffer);
301 }
302
303 return EFI_SUCCESS;
304}
305
313VOID
314EFIAPI
316 VOID
317 )
318{
319 EFI_STATUS Status;
320
321 do {
322 //
323 // Connect All EFI 1.10 drivers following EFI 1.10 algorithm
324 //
326 //
327 // Check to see if it's possible to dispatch an more DXE drivers.
328 // The BdsLibConnectAllEfi () may have made new DXE drivers show up.
329 // If anything is Dispatched Status == EFI_SUCCESS and we will try
330 // the connect again.
331 //
332 Status = gDS->Dispatch ();
333 } while (!EFI_ERROR (Status));
334}
335
353EFI_STATUS
354EFIAPI
356 IN UINT8 HostControllerPI,
357 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
358 )
359{
360 EFI_STATUS Status;
361 EFI_HANDLE *HandleArray;
362 UINTN HandleArrayCount;
363 UINTN Index;
364 EFI_PCI_IO_PROTOCOL *PciIo;
365 UINT8 Class[3];
366 BOOLEAN AtLeastOneConnected;
367
368 //
369 // Check the passed in parameters
370 //
371 if (RemainingDevicePath == NULL) {
372 return EFI_INVALID_PARAMETER;
373 }
374
375 if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||
376 ( (DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)
377 && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)
378 ))
379 {
380 return EFI_INVALID_PARAMETER;
381 }
382
383 if ((HostControllerPI != 0xFF) &&
384 (HostControllerPI != 0x00) &&
385 (HostControllerPI != 0x10) &&
386 (HostControllerPI != 0x20) &&
387 (HostControllerPI != 0x30))
388 {
389 return EFI_INVALID_PARAMETER;
390 }
391
392 //
393 // Find the usb host controller firstly, then connect with the remaining device path
394 //
395 AtLeastOneConnected = FALSE;
396 Status = gBS->LocateHandleBuffer (
397 ByProtocol,
398 &gEfiPciIoProtocolGuid,
399 NULL,
400 &HandleArrayCount,
401 &HandleArray
402 );
403 if (!EFI_ERROR (Status)) {
404 for (Index = 0; Index < HandleArrayCount; Index++) {
405 Status = gBS->HandleProtocol (
406 HandleArray[Index],
407 &gEfiPciIoProtocolGuid,
408 (VOID **)&PciIo
409 );
410 if (!EFI_ERROR (Status)) {
411 //
412 // Check whether the Pci device is the wanted usb host controller
413 //
414 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
415 if (!EFI_ERROR (Status)) {
416 if ((PCI_CLASS_SERIAL == Class[2]) &&
417 (PCI_CLASS_SERIAL_USB == Class[1]))
418 {
419 if ((HostControllerPI == Class[0]) || (HostControllerPI == 0xFF)) {
420 Status = gBS->ConnectController (
421 HandleArray[Index],
422 NULL,
423 RemainingDevicePath,
424 FALSE
425 );
426 if (!EFI_ERROR (Status)) {
427 AtLeastOneConnected = TRUE;
428 }
429 }
430 }
431 }
432 }
433 }
434
435 if (HandleArray != NULL) {
436 FreePool (HandleArray);
437 }
438
439 if (AtLeastOneConnected) {
440 return EFI_SUCCESS;
441 }
442 }
443
444 return EFI_NOT_FOUND;
445}
EFI_STATUS EFIAPI BdsLibConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect)
Definition BdsConnect.c:94
VOID BdsLibGenericConnectAll(VOID)
Definition BdsConnect.c:65
EFI_STATUS EFIAPI BdsLibConnectAllEfi(VOID)
Definition BdsConnect.c:228
EFI_STATUS EFIAPI BdsLibConnectUsbDevByShortFormDP(IN UINT8 HostControllerPI, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition BdsConnect.c:355
VOID EFIAPI BdsLibConnectAll(VOID)
Definition BdsConnect.c:36
VOID EFIAPI BdsLibConnectAllDriversToAllControllers(VOID)
Definition BdsConnect.c:315
EFI_STATUS EFIAPI BdsLibDisconnectAllEfi(VOID)
Definition BdsConnect.c:272
VOID EFIAPI BdsLibConnectAllConsoles(VOID)
Definition BdsConsole.c:429
EFI_STATUS EFIAPI BdsLibConnectAllDefaultConsoles(VOID)
Definition BdsConsole.c:506
DMG_SIZE_DEVICE_PATH Size
EFI_BOOT_SERVICES * gBS
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
EFI_GUID gEfiDevicePathProtocolGuid