OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
BdsConsole.c
Go to the documentation of this file.
1
15#include <Guid/GlobalVariable.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/UefiRuntimeServicesTableLib.h>
23
34BOOLEAN
36 IN CHAR16 *ConVarName
37 )
38{
39 CHAR16 *Ptr;
40
41 ASSERT (ConVarName != NULL);
42
43 Ptr = ConVarName;
44
45 //
46 // If the variable includes "Dev" at last, we consider
47 // it does not support NV attribute.
48 //
49 while (*Ptr != L'\0') {
50 Ptr++;
51 }
52
53 if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) {
54 return TRUE;
55 }
56
57 if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
58 return FALSE;
59 }
60
61 return TRUE;
62}
63
81BOOLEAN
83 IN CHAR16 *VarName,
84 IN EFI_GUID *ConsoleGuid,
85 IN OUT EFI_HANDLE *ConsoleHandle,
86 IN OUT VOID **ProtocolInterface
87 )
88{
89 EFI_STATUS Status;
90 UINTN DevicePathSize;
91 EFI_DEVICE_PATH_PROTOCOL *FullDevicePath;
92 EFI_DEVICE_PATH_PROTOCOL *VarConsole;
93 EFI_DEVICE_PATH_PROTOCOL *Instance;
94 VOID *Interface;
95 EFI_HANDLE NewHandle;
96
97 ASSERT (VarName != NULL);
98 ASSERT (ConsoleHandle != NULL);
99 ASSERT (ConsoleGuid != NULL);
100 ASSERT (ProtocolInterface != NULL);
101
102 if (*ConsoleHandle != NULL) {
103 Status = gBS->HandleProtocol (
104 *ConsoleHandle,
105 ConsoleGuid,
106 &Interface
107 );
108 if ((Status == EFI_SUCCESS) && (Interface == *ProtocolInterface)) {
109 //
110 // If ConsoleHandle is valid and console protocol on this handle also
111 // also matched, just return.
112 //
113 return FALSE;
114 }
115 }
116
117 //
118 // Get all possible consoles device path from EFI variable
119 //
120 VarConsole = BdsLibGetVariableAndSize (
121 VarName,
123 &DevicePathSize
124 );
125 if (VarConsole == NULL) {
126 //
127 // If there is no any console device, just return.
128 //
129 return FALSE;
130 }
131
132 FullDevicePath = VarConsole;
133
134 do {
135 //
136 // Check every instance of the console variable
137 //
138 Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
139 if (Instance == NULL) {
140 FreePool (FullDevicePath);
141 return FALSE;
142 }
143
144 //
145 // Find console device handle by device path instance
146 //
147 Status = gBS->LocateDevicePath (
148 ConsoleGuid,
149 &Instance,
150 &NewHandle
151 );
152 if (!EFI_ERROR (Status)) {
153 //
154 // Get the console protocol on this console device handle
155 //
156 Status = gBS->HandleProtocol (
157 NewHandle,
158 ConsoleGuid,
159 &Interface
160 );
161 if (!EFI_ERROR (Status)) {
162 //
163 // Update new console handle in System Table.
164 //
165 *ConsoleHandle = NewHandle;
166 *ProtocolInterface = Interface;
167 return TRUE;
168 }
169 }
170 } while (Instance != NULL);
171
172 //
173 // No any available console device found.
174 //
175 return FALSE;
176}
177
196EFI_STATUS
197EFIAPI
199 IN CHAR16 *ConVarName,
200 IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath,
201 IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath
202 )
203{
204 EFI_STATUS Status;
205 EFI_DEVICE_PATH_PROTOCOL *VarConsole;
206 UINTN DevicePathSize;
207 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
208 EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
209 UINT32 Attributes;
210
211 VarConsole = NULL;
212 DevicePathSize = 0;
213
214 //
215 // Notes: check the device path point, here should check
216 // with compare memory
217 //
218 if (CustomizedConDevicePath == ExclusiveDevicePath) {
219 return EFI_UNSUPPORTED;
220 }
221
222 //
223 // Delete the ExclusiveDevicePath from current default console
224 //
225 VarConsole = BdsLibGetVariableAndSize (
226 ConVarName,
228 &DevicePathSize
229 );
230
231 //
232 // Initialize NewDevicePath
233 //
234 NewDevicePath = VarConsole;
235
236 //
237 // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
238 // In the end, NewDevicePath is the final device path.
239 //
240 if ((ExclusiveDevicePath != NULL) && (VarConsole != NULL)) {
241 NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
242 }
243
244 //
245 // Try to append customized device path to NewDevicePath.
246 //
247 if (CustomizedConDevicePath != NULL) {
248 if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
249 //
250 // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
251 //
252 NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
253 //
254 // In the first check, the default console variable will be _ModuleEntryPoint,
255 // just append current customized device path
256 //
257 TempNewDevicePath = NewDevicePath;
258 NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
259 if (TempNewDevicePath != NULL) {
260 FreePool (TempNewDevicePath);
261 }
262 }
263 }
264
265 //
266 // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
267 //
268 if (IsNvNeed (ConVarName)) {
269 //
270 // ConVarName has NV attribute.
271 //
272 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
273 } else {
274 //
275 // ConVarName does not have NV attribute.
276 //
277 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
278 }
279
280 //
281 // Finally, Update the variable of the default console by NewDevicePath
282 //
283 DevicePathSize = GetDevicePathSize (NewDevicePath);
284 Status = gRT->SetVariable (
285 ConVarName,
287 Attributes,
288 DevicePathSize,
289 NewDevicePath
290 );
291 if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) {
292 Status = EFI_SUCCESS;
293 }
294
295 ASSERT_EFI_ERROR (Status);
296
297 if (VarConsole == NewDevicePath) {
298 if (VarConsole != NULL) {
299 FreePool (VarConsole);
300 }
301 } else {
302 if (VarConsole != NULL) {
303 FreePool (VarConsole);
304 }
305
306 if (NewDevicePath != NULL) {
307 FreePool (NewDevicePath);
308 }
309 }
310
311 return Status;
312}
313
332EFI_STATUS
333EFIAPI
335 IN CHAR16 *ConVarName
336 )
337{
338 EFI_STATUS Status;
339 EFI_DEVICE_PATH_PROTOCOL *StartDevicePath;
340 UINTN VariableSize;
341 EFI_DEVICE_PATH_PROTOCOL *Instance;
342 EFI_DEVICE_PATH_PROTOCOL *Next;
343 EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
344 UINTN Size;
345 BOOLEAN DeviceExist;
346
347 Status = EFI_SUCCESS;
348 DeviceExist = FALSE;
349
350 //
351 // Check if the console variable exist
352 //
353 StartDevicePath = BdsLibGetVariableAndSize (
354 ConVarName,
356 &VariableSize
357 );
358 if (StartDevicePath == NULL) {
359 return EFI_UNSUPPORTED;
360 }
361
362 CopyOfDevicePath = StartDevicePath;
363 do {
364 //
365 // Check every instance of the console variable
366 //
367 Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
368 if (Instance == NULL) {
369 FreePool (StartDevicePath);
370 return EFI_UNSUPPORTED;
371 }
372
373 Next = Instance;
374 while (!IsDevicePathEndType (Next)) {
375 Next = NextDevicePathNode (Next);
376 }
377
378 SetDevicePathEndNode (Next);
379 //
380 // Connect the USB console
381 // USB console device path is a short-form device path that
382 // starts with the first element being a USB WWID
383 // or a USB Class device path
384 //
385 if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
386 ( (DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
387 || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
388 ))
389 {
390 Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);
391 if (!EFI_ERROR (Status)) {
392 DeviceExist = TRUE;
393 }
394 } else {
395 //
396 // Connect the instance device path
397 //
398 Status = BdsLibConnectDevicePath (Instance);
399
400 if (EFI_ERROR (Status)) {
401 //
402 // Delete the instance from the console variable
403 //
404 BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
405 } else {
406 DeviceExist = TRUE;
407 }
408 }
409
410 FreePool (Instance);
411 } while (CopyOfDevicePath != NULL);
412
413 FreePool (StartDevicePath);
414
415 if (!DeviceExist) {
416 return EFI_NOT_FOUND;
417 }
418
419 return EFI_SUCCESS;
420}
421
427VOID
428EFIAPI
430 VOID
431 )
432{
433 UINTN Index;
434 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
435 UINTN HandleCount;
436 EFI_HANDLE *HandleBuffer;
437
438 Index = 0;
439 HandleCount = 0;
440 HandleBuffer = NULL;
441 ConDevicePath = NULL;
442
443 //
444 // Update all the console variables
445 //
446 gBS->LocateHandleBuffer (
447 ByProtocol,
448 &gEfiSimpleTextInProtocolGuid,
449 NULL,
450 &HandleCount,
451 &HandleBuffer
452 );
453
454 for (Index = 0; Index < HandleCount; Index++) {
455 gBS->HandleProtocol (
456 HandleBuffer[Index],
458 (VOID **)&ConDevicePath
459 );
460 BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
461 }
462
463 if (HandleBuffer != NULL) {
464 FreePool (HandleBuffer);
465 HandleBuffer = NULL;
466 }
467
468 gBS->LocateHandleBuffer (
469 ByProtocol,
471 NULL,
472 &HandleCount,
473 &HandleBuffer
474 );
475 for (Index = 0; Index < HandleCount; Index++) {
476 gBS->HandleProtocol (
477 HandleBuffer[Index],
479 (VOID **)&ConDevicePath
480 );
481 BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
482 BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
483 }
484
485 if (HandleBuffer != NULL) {
486 FreePool (HandleBuffer);
487 }
488
489 //
490 // Connect all console variables
491 //
493}
494
504EFI_STATUS
505EFIAPI
507 VOID
508 )
509{
510 EFI_STATUS Status;
511 BOOLEAN SystemTableUpdated;
512
513 //
514 // Connect all default console variables
515 //
516
517 //
518 // It seems impossible not to have any ConOut device on platform,
519 // so we check the status here.
520 //
521 Status = BdsLibConnectConsoleVariable (L"ConOut");
522 if (EFI_ERROR (Status)) {
523 return Status;
524 }
525
526 //
527 // Because possibly the platform is legacy free, in such case,
528 // ConIn devices (Serial Port and PS2 Keyboard ) does not exist,
529 // so we need not check the status.
530 //
532
533 //
534 // The _ModuleEntryPoint err out var is legal.
535 //
537
538 SystemTableUpdated = FALSE;
539 //
540 // Fill console handles in System Table if no console device assignd.
541 //
542 if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn)) {
543 SystemTableUpdated = TRUE;
544 }
545
546 if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut)) {
547 SystemTableUpdated = TRUE;
548 }
549
550 if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr)) {
551 SystemTableUpdated = TRUE;
552 }
553
554 if (SystemTableUpdated) {
555 //
556 // Update the CRC32 in the EFI System Table header
557 //
558 gST->Hdr.CRC32 = 0;
559 gBS->CalculateCrc32 (
560 (UINT8 *)&gST->Hdr,
561 gST->Hdr.HeaderSize,
562 &gST->Hdr.CRC32
563 );
564 }
565
566 return EFI_SUCCESS;
567}
VOID EFIAPI BdsLibConnectAllConsoles(VOID)
Definition BdsConsole.c:429
EFI_STATUS EFIAPI BdsLibConnectAllDefaultConsoles(VOID)
Definition BdsConsole.c:506
EFI_STATUS EFIAPI BdsLibUpdateConsoleVariable(IN CHAR16 *ConVarName, IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath)
Definition BdsConsole.c:198
BOOLEAN IsNvNeed(IN CHAR16 *ConVarName)
Definition BdsConsole.c:35
EFI_STATUS EFIAPI BdsLibConnectConsoleVariable(IN CHAR16 *ConVarName)
Definition BdsConsole.c:334
BOOLEAN UpdateSystemTableConsole(IN CHAR16 *VarName, IN EFI_GUID *ConsoleGuid, IN OUT EFI_HANDLE *ConsoleHandle, IN OUT VOID **ProtocolInterface)
Definition BdsConsole.c:82
EFI_STATUS EFIAPI BdsLibConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect)
Definition BdsConnect.c:94
EFI_STATUS EFIAPI BdsLibConnectUsbDevByShortFormDP(IN UINT8 HostControllerPI, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition BdsConnect.c:355
EFI_DEVICE_PATH_PROTOCOL *EFIAPI BdsLibDelPartMatchInstance(IN EFI_DEVICE_PATH_PROTOCOL *Multi, IN EFI_DEVICE_PATH_PROTOCOL *Single)
Definition BdsMisc.c:93
BOOLEAN EFIAPI BdsLibMatchDevicePaths(IN EFI_DEVICE_PATH_PROTOCOL *Multi, IN EFI_DEVICE_PATH_PROTOCOL *Single)
Definition BdsMisc.c:153
VOID *EFIAPI BdsLibGetVariableAndSize(IN CHAR16 *Name, IN EFI_GUID *VendorGuid, OUT UINTN *VariableSize)
Definition BdsMisc.c:36
DMG_SIZE_DEVICE_PATH Size
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
EFI_RUNTIME_SERVICES * gRT
EFI_GUID gEfiSimpleTextOutProtocolGuid
EFI_GUID gEfiGlobalVariableGuid
EFI_GUID gEfiDevicePathProtocolGuid
#define ASSERT(x)
Definition coder.h:55