VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/BootMaintenanceManagerUiLib/ConsoleOption.c@ 95057

最後變更 在這個檔案從95057是 85718,由 vboxsync 提交於 5 年 前

Devices/EFI: Merge edk-stable202005 and make it build, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 33.4 KB
 
1/** @file
2handles console redirection from boot manager
3
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include "BootMaintenanceManager.h"
10
11/**
12 Function compares a device path data structure to that of all the nodes of a
13 second device path instance.
14
15 @param Multi A pointer to a multi-instance device path data
16 structure.
17 @param Single A pointer to a single-instance device path data
18 structure.
19
20 @retval TRUE If the Single device path is contained within Multi device path.
21 @retval FALSE The Single device path is not match within Multi device path.
22
23**/
24BOOLEAN
25MatchDevicePaths (
26 IN EFI_DEVICE_PATH_PROTOCOL *Multi,
27 IN EFI_DEVICE_PATH_PROTOCOL *Single
28 )
29{
30 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
31 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
32 UINTN Size;
33
34 if (Multi == NULL || Single == NULL) {
35 return FALSE;
36 }
37
38 DevicePath = Multi;
39 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
40
41 //
42 // Search for the match of 'Single' in 'Multi'
43 //
44 while (DevicePathInst != NULL) {
45 //
46 // If the single device path is found in multiple device paths,
47 // return success
48 //
49 if (CompareMem (Single, DevicePathInst, Size) == 0) {
50 FreePool (DevicePathInst);
51 return TRUE;
52 }
53
54 FreePool (DevicePathInst);
55 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
56 }
57
58 return FALSE;
59}
60
61/**
62 Check whether the device path node is ISA Serial Node.
63
64 @param Acpi Device path node to be checked
65
66 @retval TRUE It's ISA Serial Node.
67 @retval FALSE It's NOT ISA Serial Node.
68
69**/
70BOOLEAN
71IsIsaSerialNode (
72 IN ACPI_HID_DEVICE_PATH *Acpi
73 )
74{
75 return (BOOLEAN) (
76 (DevicePathType (Acpi) == ACPI_DEVICE_PATH) &&
77 (DevicePathSubType (Acpi) == ACPI_DP) &&
78 (ReadUnaligned32 (&Acpi->HID) == EISA_PNP_ID (0x0501))
79 );
80}
81
82/**
83 Update Com Ports attributes from DevicePath
84
85 @param DevicePath DevicePath that contains Com ports
86
87 @retval EFI_SUCCESS The update is successful.
88
89**/
90EFI_STATUS
91UpdateComAttributeFromVariable (
92 EFI_DEVICE_PATH_PROTOCOL *DevicePath
93 );
94
95/**
96 Update the multi-instance device path of Terminal Device based on
97 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal
98 device path in the Terminal Device in TerminalMenu is also updated.
99
100 @param DevicePath The multi-instance device path.
101 @param ChangeTerminal TRUE, then device path in the Terminal Device
102 in TerminalMenu is also updated; FALSE, no update.
103
104 @return EFI_SUCCESS The function completes successfully.
105
106**/
107EFI_STATUS
108ChangeTerminalDevicePath (
109 IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
110 IN BOOLEAN ChangeTerminal
111 )
112{
113 EFI_DEVICE_PATH_PROTOCOL *Node;
114 EFI_DEVICE_PATH_PROTOCOL *Node1;
115 ACPI_HID_DEVICE_PATH *Acpi;
116 UART_DEVICE_PATH *Uart;
117 UART_DEVICE_PATH *Uart1;
118 UINTN Com;
119 BM_TERMINAL_CONTEXT *NewTerminalContext;
120 BM_MENU_ENTRY *NewMenuEntry;
121
122 Node = DevicePath;
123 Node = NextDevicePathNode (Node);
124 Com = 0;
125 while (!IsDevicePathEnd (Node)) {
126 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
127 if (IsIsaSerialNode (Acpi)) {
128 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
129 }
130
131 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);
132
133 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
134 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
135 Uart = (UART_DEVICE_PATH *) Node;
136 CopyMem (
137 &Uart->BaudRate,
138 &NewTerminalContext->BaudRate,
139 sizeof (UINT64)
140 );
141
142 CopyMem (
143 &Uart->DataBits,
144 &NewTerminalContext->DataBits,
145 sizeof (UINT8)
146 );
147
148 CopyMem (
149 &Uart->Parity,
150 &NewTerminalContext->Parity,
151 sizeof (UINT8)
152 );
153
154 CopyMem (
155 &Uart->StopBits,
156 &NewTerminalContext->StopBits,
157 sizeof (UINT8)
158 );
159 //
160 // Change the device path in the ComPort
161 //
162 if (ChangeTerminal) {
163 Node1 = NewTerminalContext->DevicePath;
164 Node1 = NextDevicePathNode (Node1);
165 while (!IsDevicePathEnd (Node1)) {
166 if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {
167 Uart1 = (UART_DEVICE_PATH *) Node1;
168 CopyMem (
169 &Uart1->BaudRate,
170 &NewTerminalContext->BaudRate,
171 sizeof (UINT64)
172 );
173
174 CopyMem (
175 &Uart1->DataBits,
176 &NewTerminalContext->DataBits,
177 sizeof (UINT8)
178 );
179
180 CopyMem (
181 &Uart1->Parity,
182 &NewTerminalContext->Parity,
183 sizeof (UINT8)
184 );
185
186 CopyMem (
187 &Uart1->StopBits,
188 &NewTerminalContext->StopBits,
189 sizeof (UINT8)
190 );
191 break;
192 }
193 //
194 // end if
195 //
196 Node1 = NextDevicePathNode (Node1);
197 }
198 //
199 // end while
200 //
201 break;
202 }
203 }
204
205 Node = NextDevicePathNode (Node);
206 }
207
208 return EFI_SUCCESS;
209
210}
211
212/**
213 Update the device path that describing a terminal device
214 based on the new BaudRate, Data Bits, parity and Stop Bits
215 set.
216
217 @param DevicePath terminal device's path
218
219**/
220VOID
221ChangeVariableDevicePath (
222 IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath
223 )
224{
225 EFI_DEVICE_PATH_PROTOCOL *Node;
226 ACPI_HID_DEVICE_PATH *Acpi;
227 UART_DEVICE_PATH *Uart;
228 UINTN Com;
229 BM_TERMINAL_CONTEXT *NewTerminalContext;
230 BM_MENU_ENTRY *NewMenuEntry;
231
232 Node = DevicePath;
233 Node = NextDevicePathNode (Node);
234 Com = 0;
235 while (!IsDevicePathEnd (Node)) {
236 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
237 if (IsIsaSerialNode (Acpi)) {
238 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
239 }
240
241 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
242 NewMenuEntry = BOpt_GetMenuEntry (
243 &TerminalMenu,
244 Com
245 );
246 ASSERT (NewMenuEntry != NULL);
247 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
248 Uart = (UART_DEVICE_PATH *) Node;
249 CopyMem (
250 &Uart->BaudRate,
251 &NewTerminalContext->BaudRate,
252 sizeof (UINT64)
253 );
254
255 CopyMem (
256 &Uart->DataBits,
257 &NewTerminalContext->DataBits,
258 sizeof (UINT8)
259 );
260
261 CopyMem (
262 &Uart->Parity,
263 &NewTerminalContext->Parity,
264 sizeof (UINT8)
265 );
266
267 CopyMem (
268 &Uart->StopBits,
269 &NewTerminalContext->StopBits,
270 sizeof (UINT8)
271 );
272 }
273
274 Node = NextDevicePathNode (Node);
275 }
276}
277
278/**
279 Retrieve ACPI UID of UART from device path
280
281 @param Handle The handle for the UART device.
282 @param AcpiUid The ACPI UID on output.
283
284 @retval TRUE Find valid UID from device path
285 @retval FALSE Can't find
286
287**/
288BOOLEAN
289RetrieveUartUid (
290 IN EFI_HANDLE Handle,
291 IN OUT UINT32 *AcpiUid
292 )
293{
294 EFI_STATUS Status;
295 ACPI_HID_DEVICE_PATH *Acpi;
296 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
297
298 Status = gBS->HandleProtocol (
299 Handle,
300 &gEfiDevicePathProtocolGuid,
301 (VOID **) &DevicePath
302 );
303 if (EFI_ERROR (Status)) {
304 return FALSE;
305 }
306
307 Acpi = NULL;
308 for (; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
309 if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_UART_DP)) {
310 break;
311 }
312 //
313 // Acpi points to the node before the Uart node
314 //
315 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
316 }
317
318 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
319 if (AcpiUid != NULL) {
320 CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32));
321 }
322 return TRUE;
323 } else {
324 return FALSE;
325 }
326}
327
328/**
329 Sort Uart handles array with Acpi->UID from low to high.
330
331 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer
332 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count
333**/
334VOID
335SortedUartHandle (
336 IN EFI_HANDLE *Handles,
337 IN UINTN NoHandles
338 )
339{
340 UINTN Index1;
341 UINTN Index2;
342 UINTN Position;
343 UINT32 AcpiUid1;
344 UINT32 AcpiUid2;
345 UINT32 TempAcpiUid;
346 EFI_HANDLE TempHandle;
347
348 for (Index1 = 0; Index1 < NoHandles-1; Index1++) {
349 if (!RetrieveUartUid (Handles[Index1], &AcpiUid1)) {
350 continue;
351 }
352 TempHandle = Handles[Index1];
353 Position = Index1;
354 TempAcpiUid = AcpiUid1;
355
356 for (Index2 = Index1+1; Index2 < NoHandles; Index2++) {
357 if (!RetrieveUartUid (Handles[Index2], &AcpiUid2)) {
358 continue;
359 }
360 if (AcpiUid2 < TempAcpiUid) {
361 TempAcpiUid = AcpiUid2;
362 TempHandle = Handles[Index2];
363 Position = Index2;
364 }
365 }
366 Handles[Position] = Handles[Index1];
367 Handles[Index1] = TempHandle;
368 }
369}
370
371/**
372 Test whether DevicePath is a valid Terminal
373
374
375 @param DevicePath DevicePath to be checked
376 @param Termi If DevicePath is valid Terminal, terminal type is returned.
377 @param Com If DevicePath is valid Terminal, Com Port type is returned.
378
379 @retval TRUE If DevicePath point to a Terminal.
380 @retval FALSE If DevicePath does not point to a Terminal.
381
382**/
383BOOLEAN
384IsTerminalDevicePath (
385 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
386 OUT TYPE_OF_TERMINAL *Termi,
387 OUT UINTN *Com
388 );
389
390/**
391 Build a list containing all serial devices.
392
393
394 @retval EFI_SUCCESS The function complete successfully.
395 @retval EFI_UNSUPPORTED No serial ports present.
396
397**/
398EFI_STATUS
399LocateSerialIo (
400 VOID
401 )
402{
403 UINTN Index;
404 UINTN Index2;
405 UINTN NoHandles;
406 EFI_HANDLE *Handles;
407 EFI_STATUS Status;
408 ACPI_HID_DEVICE_PATH *Acpi;
409 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
410 EFI_SERIAL_IO_PROTOCOL *SerialIo;
411 EFI_DEVICE_PATH_PROTOCOL *Node;
412 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
413 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
414 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
415 BM_MENU_ENTRY *NewMenuEntry;
416 BM_TERMINAL_CONTEXT *NewTerminalContext;
417 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
418 VENDOR_DEVICE_PATH Vendor;
419
420 //
421 // Get all handles that have SerialIo protocol installed
422 //
423 InitializeListHead (&TerminalMenu.Head);
424 TerminalMenu.MenuNumber = 0;
425 Status = gBS->LocateHandleBuffer (
426 ByProtocol,
427 &gEfiSerialIoProtocolGuid,
428 NULL,
429 &NoHandles,
430 &Handles
431 );
432 if (EFI_ERROR (Status)) {
433 //
434 // No serial ports present
435 //
436 return EFI_UNSUPPORTED;
437 }
438
439 //
440 // Sort Uart handles array with Acpi->UID from low to high
441 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
442 //
443 SortedUartHandle (Handles, NoHandles);
444
445 for (Index = 0; Index < NoHandles; Index++) {
446 //
447 // Check to see whether the handle has DevicePath Protocol installed
448 //
449 gBS->HandleProtocol (
450 Handles[Index],
451 &gEfiDevicePathProtocolGuid,
452 (VOID **) &DevicePath
453 );
454
455 Acpi = NULL;
456 for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
457 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
458 break;
459 }
460 //
461 // Acpi points to the node before Uart node
462 //
463 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
464 }
465
466 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
467 NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
468 if (NewMenuEntry == NULL) {
469 FreePool (Handles);
470 return EFI_OUT_OF_RESOURCES;
471 }
472
473 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
474 CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
475 NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);
476 //
477 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
478 // coz' the misc data for each platform is not correct, actually it's the device path stored in
479 // datahub which is not completed, so a searching for end of device path will enter a
480 // dead-loop.
481 //
482 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
483 if (NULL == NewMenuEntry->DisplayString) {
484 NewMenuEntry->DisplayString = UiDevicePathToStr (DevicePath);
485 }
486
487 NewMenuEntry->HelpString = NULL;
488
489 NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
490
491 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
492
493 gBS->HandleProtocol (
494 Handles[Index],
495 &gEfiSerialIoProtocolGuid,
496 (VOID **) &SerialIo
497 );
498
499 CopyMem (
500 &NewTerminalContext->BaudRate,
501 &SerialIo->Mode->BaudRate,
502 sizeof (UINT64)
503 );
504
505 CopyMem (
506 &NewTerminalContext->DataBits,
507 &SerialIo->Mode->DataBits,
508 sizeof (UINT8)
509 );
510
511 CopyMem (
512 &NewTerminalContext->Parity,
513 &SerialIo->Mode->Parity,
514 sizeof (UINT8)
515 );
516
517 CopyMem (
518 &NewTerminalContext->StopBits,
519 &SerialIo->Mode->StopBits,
520 sizeof (UINT8)
521 );
522 InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
523 TerminalMenu.MenuNumber++;
524 }
525 }
526 if (Handles != NULL) {
527 FreePool (Handles);
528 }
529
530 //
531 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
532 //
533 GetEfiGlobalVariable2 (L"ConOut", (VOID**)&OutDevicePath, NULL);
534 GetEfiGlobalVariable2 (L"ConIn", (VOID**)&InpDevicePath, NULL);
535 GetEfiGlobalVariable2 (L"ErrOut", (VOID**)&ErrDevicePath, NULL);
536 if (OutDevicePath != NULL) {
537 UpdateComAttributeFromVariable (OutDevicePath);
538 }
539
540 if (InpDevicePath != NULL) {
541 UpdateComAttributeFromVariable (InpDevicePath);
542 }
543
544 if (ErrDevicePath != NULL) {
545 UpdateComAttributeFromVariable (ErrDevicePath);
546 }
547
548 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
549 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
550 if (NULL == NewMenuEntry) {
551 return EFI_NOT_FOUND;
552 }
553
554 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
555
556 NewTerminalContext->TerminalType = 0;
557 NewTerminalContext->IsConIn = FALSE;
558 NewTerminalContext->IsConOut = FALSE;
559 NewTerminalContext->IsStdErr = FALSE;
560
561 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
562 Vendor.Header.SubType = MSG_VENDOR_DP;
563
564 for (Index2 = 0; Index2 < (ARRAY_SIZE (TerminalTypeGuid)); Index2++) {
565 CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));
566 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
567 NewDevicePath = AppendDevicePathNode (
568 NewTerminalContext->DevicePath,
569 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
570 );
571 if (NewMenuEntry->HelpString != NULL) {
572 FreePool (NewMenuEntry->HelpString);
573 }
574 //
575 // NewMenuEntry->HelpString = UiDevicePathToStr (NewDevicePath);
576 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
577 //
578 NewMenuEntry->HelpString = NULL;
579
580 NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
581
582 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
583
584 if (MatchDevicePaths (OutDevicePath, NewDevicePath)) {
585 NewTerminalContext->IsConOut = TRUE;
586 NewTerminalContext->TerminalType = (UINT8) Index2;
587 }
588
589 if (MatchDevicePaths (InpDevicePath, NewDevicePath)) {
590 NewTerminalContext->IsConIn = TRUE;
591 NewTerminalContext->TerminalType = (UINT8) Index2;
592 }
593
594 if (MatchDevicePaths (ErrDevicePath, NewDevicePath)) {
595 NewTerminalContext->IsStdErr = TRUE;
596 NewTerminalContext->TerminalType = (UINT8) Index2;
597 }
598 }
599 }
600
601 return EFI_SUCCESS;
602}
603
604/**
605 Update Com Ports attributes from DevicePath
606
607 @param DevicePath DevicePath that contains Com ports
608
609 @retval EFI_SUCCESS The update is successful.
610 @retval EFI_NOT_FOUND Can not find specific menu entry
611**/
612EFI_STATUS
613UpdateComAttributeFromVariable (
614 EFI_DEVICE_PATH_PROTOCOL *DevicePath
615 )
616{
617 EFI_DEVICE_PATH_PROTOCOL *Node;
618 EFI_DEVICE_PATH_PROTOCOL *SerialNode;
619 ACPI_HID_DEVICE_PATH *Acpi;
620 UART_DEVICE_PATH *Uart;
621 UART_DEVICE_PATH *Uart1;
622 UINTN TerminalNumber;
623 BM_MENU_ENTRY *NewMenuEntry;
624 BM_TERMINAL_CONTEXT *NewTerminalContext;
625 UINTN Index;
626
627 Node = DevicePath;
628 Node = NextDevicePathNode (Node);
629 TerminalNumber = 0;
630 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
631 while (!IsDevicePathEnd (Node)) {
632 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
633 if (IsIsaSerialNode (Acpi)) {
634 CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));
635 }
636
637 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
638 Uart = (UART_DEVICE_PATH *) Node;
639 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);
640 if (NULL == NewMenuEntry) {
641 return EFI_NOT_FOUND;
642 }
643
644 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
645 CopyMem (
646 &NewTerminalContext->BaudRate,
647 &Uart->BaudRate,
648 sizeof (UINT64)
649 );
650
651 CopyMem (
652 &NewTerminalContext->DataBits,
653 &Uart->DataBits,
654 sizeof (UINT8)
655 );
656
657 CopyMem (
658 &NewTerminalContext->Parity,
659 &Uart->Parity,
660 sizeof (UINT8)
661 );
662
663 CopyMem (
664 &NewTerminalContext->StopBits,
665 &Uart->StopBits,
666 sizeof (UINT8)
667 );
668
669 SerialNode = NewTerminalContext->DevicePath;
670 SerialNode = NextDevicePathNode (SerialNode);
671 while (!IsDevicePathEnd (SerialNode)) {
672 if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {
673 //
674 // Update following device paths according to
675 // previous acquired uart attributes
676 //
677 Uart1 = (UART_DEVICE_PATH *) SerialNode;
678 CopyMem (
679 &Uart1->BaudRate,
680 &NewTerminalContext->BaudRate,
681 sizeof (UINT64)
682 );
683
684 CopyMem (
685 &Uart1->DataBits,
686 &NewTerminalContext->DataBits,
687 sizeof (UINT8)
688 );
689 CopyMem (
690 &Uart1->Parity,
691 &NewTerminalContext->Parity,
692 sizeof (UINT8)
693 );
694 CopyMem (
695 &Uart1->StopBits,
696 &NewTerminalContext->StopBits,
697 sizeof (UINT8)
698 );
699
700 break;
701 }
702
703 SerialNode = NextDevicePathNode (SerialNode);
704 }
705 //
706 // end while
707 //
708 }
709
710 Node = NextDevicePathNode (Node);
711 }
712 //
713 // end while
714 //
715 }
716
717 return EFI_SUCCESS;
718}
719
720/**
721 Build up Console Menu based on types passed in. The type can
722 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
723 and BM_CONSOLE_ERR_CONTEXT_SELECT.
724
725 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
726 and BM_CONSOLE_ERR_CONTEXT_SELECT.
727
728 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
729 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev",
730 "ConInDev" or "ConErrDev" doesn't exists.
731 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
732 @retval EFI_SUCCESS Function completes successfully.
733
734**/
735EFI_STATUS
736GetConsoleMenu (
737 IN UINTN ConsoleMenuType
738 )
739{
740 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
741 EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;
742 EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;
743 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
744 UINTN Size;
745 UINTN AllCount;
746 UINTN Index;
747 UINTN Index2;
748 BM_MENU_ENTRY *NewMenuEntry;
749 BM_CONSOLE_CONTEXT *NewConsoleContext;
750 TYPE_OF_TERMINAL Terminal;
751 UINTN Com;
752 BM_MENU_OPTION *ConsoleMenu;
753
754 DevicePath = NULL;
755 AllDevicePath = NULL;
756 AllCount = 0;
757 switch (ConsoleMenuType) {
758 case BM_CONSOLE_IN_CONTEXT_SELECT:
759 ConsoleMenu = &ConsoleInpMenu;
760 GetEfiGlobalVariable2 (L"ConIn", (VOID**)&DevicePath, NULL);
761 GetEfiGlobalVariable2 (L"ConInDev", (VOID**)&AllDevicePath, NULL);
762 break;
763
764 case BM_CONSOLE_OUT_CONTEXT_SELECT:
765 ConsoleMenu = &ConsoleOutMenu;
766 GetEfiGlobalVariable2 (L"ConOut", (VOID**)&DevicePath, NULL);
767 GetEfiGlobalVariable2 (L"ConOutDev", (VOID**)&AllDevicePath, NULL);
768 break;
769
770 case BM_CONSOLE_ERR_CONTEXT_SELECT:
771 ConsoleMenu = &ConsoleErrMenu;
772 GetEfiGlobalVariable2 (L"ErrOut", (VOID**)&DevicePath, NULL);
773 GetEfiGlobalVariable2 (L"ErrOutDev", (VOID**)&AllDevicePath, NULL);
774 break;
775
776 default:
777 return EFI_UNSUPPORTED;
778 }
779
780 if (NULL == AllDevicePath) {
781 return EFI_NOT_FOUND;
782 }
783
784 InitializeListHead (&ConsoleMenu->Head);
785
786 AllCount = EfiDevicePathInstanceCount (AllDevicePath);
787 ConsoleMenu->MenuNumber = 0;
788 //
789 // Following is menu building up for Console Devices selected.
790 //
791 MultiDevicePath = AllDevicePath;
792 Index2 = 0;
793 for (Index = 0; Index < AllCount; Index++) {
794 DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);
795
796 NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
797 if (NULL == NewMenuEntry) {
798 return EFI_OUT_OF_RESOURCES;
799 }
800
801 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
802 NewMenuEntry->OptionNumber = Index2;
803
804 NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);
805 ASSERT (NewConsoleContext->DevicePath != NULL);
806 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
807 if (NULL == NewMenuEntry->DisplayString) {
808 NewMenuEntry->DisplayString = UiDevicePathToStr (NewConsoleContext->DevicePath);
809 }
810
811 NewMenuEntry->DisplayStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
812
813 if (NULL == NewMenuEntry->HelpString) {
814 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
815 } else {
816 NewMenuEntry->HelpStringToken = HiiSetString (mBmmCallbackInfo->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);
817 }
818
819 NewConsoleContext->IsTerminal = IsTerminalDevicePath (
820 NewConsoleContext->DevicePath,
821 &Terminal,
822 &Com
823 );
824
825 NewConsoleContext->IsActive = MatchDevicePaths (
826 DevicePath,
827 NewConsoleContext->DevicePath
828 );
829
830 if (NewConsoleContext->IsTerminal) {
831 BOpt_DestroyMenuEntry (NewMenuEntry);
832 } else {
833 Index2++;
834 ConsoleMenu->MenuNumber++;
835 InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
836 }
837 }
838
839 return EFI_SUCCESS;
840}
841
842/**
843 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
844
845 @retval EFI_SUCCESS The function always complete successfully.
846
847**/
848EFI_STATUS
849GetAllConsoles (
850 VOID
851 )
852{
853 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
854 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
855 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
856 return EFI_SUCCESS;
857}
858
859/**
860 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
861
862 @retval EFI_SUCCESS The function always complete successfully.
863**/
864EFI_STATUS
865FreeAllConsoles (
866 VOID
867 )
868{
869 BOpt_FreeMenu (&ConsoleOutMenu);
870 BOpt_FreeMenu (&ConsoleInpMenu);
871 BOpt_FreeMenu (&ConsoleErrMenu);
872 BOpt_FreeMenu (&TerminalMenu);
873 return EFI_SUCCESS;
874}
875
876/**
877 Test whether DevicePath is a valid Terminal
878
879
880 @param DevicePath DevicePath to be checked
881 @param Termi If DevicePath is valid Terminal, terminal type is returned.
882 @param Com If DevicePath is valid Terminal, Com Port type is returned.
883
884 @retval TRUE If DevicePath point to a Terminal.
885 @retval FALSE If DevicePath does not point to a Terminal.
886
887**/
888BOOLEAN
889IsTerminalDevicePath (
890 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
891 OUT TYPE_OF_TERMINAL *Termi,
892 OUT UINTN *Com
893 )
894{
895 BOOLEAN IsTerminal;
896 EFI_DEVICE_PATH_PROTOCOL *Node;
897 VENDOR_DEVICE_PATH *Vendor;
898 UART_DEVICE_PATH *Uart;
899 ACPI_HID_DEVICE_PATH *Acpi;
900 UINTN Index;
901
902 IsTerminal = FALSE;
903
904 Uart = NULL;
905 Vendor = NULL;
906 Acpi = NULL;
907 for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
908 //
909 // Vendor points to the node before the End node
910 //
911 Vendor = (VENDOR_DEVICE_PATH *) Node;
912
913 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
914 Uart = (UART_DEVICE_PATH *) Node;
915 }
916
917 if (Uart == NULL) {
918 //
919 // Acpi points to the node before the UART node
920 //
921 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
922 }
923 }
924
925 if (Vendor == NULL ||
926 DevicePathType (Vendor) != MESSAGING_DEVICE_PATH ||
927 DevicePathSubType (Vendor) != MSG_VENDOR_DP ||
928 Uart == NULL) {
929 return FALSE;
930 }
931
932 //
933 // There are 9 kinds of Terminal types
934 // check to see whether this devicepath
935 // is one of that type
936 //
937 for (Index = 0; Index < ARRAY_SIZE (TerminalTypeGuid); Index++) {
938 if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[Index])) {
939 *Termi = Index;
940 IsTerminal = TRUE;
941 break;
942 }
943 }
944
945 if (Index == ARRAY_SIZE (TerminalTypeGuid)) {
946 IsTerminal = FALSE;
947 }
948
949 if (!IsTerminal) {
950 return FALSE;
951 }
952
953 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
954 CopyMem (Com, &Acpi->UID, sizeof (UINT32));
955 } else {
956 return FALSE;
957 }
958
959 return TRUE;
960}
961
962/**
963 Get mode number according to column and row
964
965 @param CallbackData The BMM context data.
966**/
967VOID
968GetConsoleOutMode (
969 IN BMM_CALLBACK_DATA *CallbackData
970 )
971{
972 UINTN Col;
973 UINTN Row;
974 UINTN CurrentCol;
975 UINTN CurrentRow;
976 UINTN Mode;
977 UINTN MaxMode;
978 EFI_STATUS Status;
979 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
980
981 ConOut = gST->ConOut;
982 MaxMode = (UINTN) (ConOut->Mode->MaxMode);
983
984 CurrentCol = PcdGet32 (PcdSetupConOutColumn);
985 CurrentRow = PcdGet32 (PcdSetupConOutRow);
986 for (Mode = 0; Mode < MaxMode; Mode++) {
987 Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
988 if (!EFI_ERROR(Status)) {
989 if (CurrentCol == Col && CurrentRow == Row) {
990 CallbackData->BmmFakeNvData.ConsoleOutMode = (UINT16) Mode;
991 break;
992 }
993 }
994 }
995}
996
997/**
998
999 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]
1000 in BMM_FAKE_NV_DATA structure.
1001
1002 @param CallbackData The BMM context data.
1003
1004**/
1005VOID
1006GetConsoleInCheck (
1007 IN BMM_CALLBACK_DATA *CallbackData
1008 )
1009{
1010 UINT16 Index;
1011 BM_MENU_ENTRY *NewMenuEntry;
1012 UINT8 *ConInCheck;
1013 BM_CONSOLE_CONTEXT *NewConsoleContext;
1014 BM_TERMINAL_CONTEXT *NewTerminalContext;
1015
1016 ASSERT (CallbackData != NULL);
1017
1018 ConInCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
1019 for (Index = 0; ((Index < ConsoleInpMenu.MenuNumber) && \
1020 (Index < MAX_MENU_NUMBER)) ; Index++) {
1021 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
1022 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1023 ConInCheck[Index] = NewConsoleContext->IsActive;
1024 }
1025
1026 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1027 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1028 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1029 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
1030 ConInCheck[Index + ConsoleInpMenu.MenuNumber] = NewTerminalContext->IsConIn;
1031 }
1032}
1033
1034/**
1035
1036 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]
1037 in BMM_FAKE_NV_DATA structure.
1038
1039 @param CallbackData The BMM context data.
1040
1041**/
1042VOID
1043GetConsoleOutCheck (
1044 IN BMM_CALLBACK_DATA *CallbackData
1045 )
1046{
1047 UINT16 Index;
1048 BM_MENU_ENTRY *NewMenuEntry;
1049 UINT8 *ConOutCheck;
1050 BM_CONSOLE_CONTEXT *NewConsoleContext;
1051 BM_TERMINAL_CONTEXT *NewTerminalContext;
1052
1053 ASSERT (CallbackData != NULL);
1054 ConOutCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
1055 for (Index = 0; ((Index < ConsoleOutMenu.MenuNumber) && \
1056 (Index < MAX_MENU_NUMBER)) ; Index++) {
1057 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
1058 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1059 ConOutCheck[Index] = NewConsoleContext->IsActive;
1060 }
1061
1062 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1063 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1064 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1065 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
1066 ConOutCheck[Index + ConsoleOutMenu.MenuNumber] = NewTerminalContext->IsConOut;
1067 }
1068}
1069
1070/**
1071
1072 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]
1073 in BMM_FAKE_NV_DATA structure.
1074
1075 @param CallbackData The BMM context data.
1076
1077**/
1078VOID
1079GetConsoleErrCheck (
1080 IN BMM_CALLBACK_DATA *CallbackData
1081 )
1082{
1083 UINT16 Index;
1084 BM_MENU_ENTRY *NewMenuEntry;
1085 UINT8 *ConErrCheck;
1086 BM_CONSOLE_CONTEXT *NewConsoleContext;
1087 BM_TERMINAL_CONTEXT *NewTerminalContext;
1088
1089 ASSERT (CallbackData != NULL);
1090 ConErrCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
1091 for (Index = 0; ((Index < ConsoleErrMenu.MenuNumber) && \
1092 (Index < MAX_MENU_NUMBER)) ; Index++) {
1093 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
1094 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
1095 ConErrCheck[Index] = NewConsoleContext->IsActive;
1096 }
1097
1098 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
1099 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
1100 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1101 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
1102 ConErrCheck[Index + ConsoleErrMenu.MenuNumber] = NewTerminalContext->IsStdErr;
1103 }
1104}
1105
1106/**
1107
1108 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)
1109 to BMM_FAKE_NV_DATA structure.
1110
1111 @param CallbackData The BMM context data.
1112
1113**/
1114VOID
1115GetTerminalAttribute (
1116 IN BMM_CALLBACK_DATA *CallbackData
1117 )
1118{
1119 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
1120 BM_MENU_ENTRY *NewMenuEntry;
1121 BM_TERMINAL_CONTEXT *NewTerminalContext;
1122 UINT16 TerminalIndex;
1123 UINT8 AttributeIndex;
1124
1125 ASSERT (CallbackData != NULL);
1126
1127 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
1128 for (TerminalIndex = 0; ((TerminalIndex < TerminalMenu.MenuNumber) && \
1129 (TerminalIndex < MAX_MENU_NUMBER)); TerminalIndex++) {
1130 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalIndex);
1131 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
1132 for (AttributeIndex = 0; AttributeIndex < sizeof (BaudRateList) / sizeof (BaudRateList [0]); AttributeIndex++) {
1133 if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[AttributeIndex].Value)) {
1134 NewTerminalContext->BaudRateIndex = AttributeIndex;
1135 break;
1136 }
1137 }
1138 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (DataBitsList); AttributeIndex++) {
1139 if (NewTerminalContext->DataBits == (UINT64) (DataBitsList[AttributeIndex].Value)) {
1140 NewTerminalContext->DataBitsIndex = AttributeIndex;
1141 break;
1142 }
1143 }
1144
1145 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (ParityList); AttributeIndex++) {
1146 if (NewTerminalContext->Parity == (UINT64) (ParityList[AttributeIndex].Value)) {
1147 NewTerminalContext->ParityIndex = AttributeIndex;
1148 break;
1149 }
1150 }
1151
1152 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (StopBitsList); AttributeIndex++) {
1153 if (NewTerminalContext->StopBits == (UINT64) (StopBitsList[AttributeIndex].Value)) {
1154 NewTerminalContext->StopBitsIndex = AttributeIndex;
1155 break;
1156 }
1157 }
1158 CurrentFakeNVMap->COMBaudRate[TerminalIndex] = NewTerminalContext->BaudRateIndex;
1159 CurrentFakeNVMap->COMDataRate[TerminalIndex] = NewTerminalContext->DataBitsIndex;
1160 CurrentFakeNVMap->COMStopBits[TerminalIndex] = NewTerminalContext->StopBitsIndex;
1161 CurrentFakeNVMap->COMParity[TerminalIndex] = NewTerminalContext->ParityIndex;
1162 CurrentFakeNVMap->COMTerminalType[TerminalIndex] = NewTerminalContext->TerminalType;
1163 CurrentFakeNVMap->COMFlowControl[TerminalIndex] = NewTerminalContext->FlowControl;
1164 }
1165}
1166
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette