]> git.proxmox.com Git - mirror_edk2.git/blob - EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c
c77fa0a351eda1fe28981ffbbc278a49151f9e96
[mirror_edk2.git] / EdkNt32Pkg / Dxe / PlatformBds / Generic / BootMaint / ConsoleOption.c
1 /*++
2 Copyright (c) 2006, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
7
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11 Module Name:
12
13 ConsoleOption.c
14
15 Abstract:
16
17 handles console redirection from boot manager
18
19
20 Revision History
21
22 --*/
23
24 #include "BootMaint.h"
25
26 EFI_DEVICE_PATH_PROTOCOL *
27 DevicePathInstanceDup (
28 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
29 );
30
31 EFI_STATUS
32 UpdateComAttributeFromVariable (
33 EFI_DEVICE_PATH_PROTOCOL *DevicePath
34 );
35
36 EFI_STATUS
37 ChangeTerminalDevicePath (
38 EFI_DEVICE_PATH_PROTOCOL *DevicePath,
39 BOOLEAN ChangeTerminal
40 )
41 {
42 EFI_DEVICE_PATH_PROTOCOL *Node;
43 EFI_DEVICE_PATH_PROTOCOL *Node1;
44 ACPI_HID_DEVICE_PATH *Acpi;
45 UART_DEVICE_PATH *Uart;
46 UART_DEVICE_PATH *Uart1;
47 UINTN Com;
48 UINT32 Match;
49 BM_TERMINAL_CONTEXT *NewTerminalContext;
50 BM_MENU_ENTRY *NewMenuEntry;
51
52 Match = EISA_PNP_ID (0x0501);
53 Node = DevicePath;
54 Node = NextDevicePathNode (Node);
55 Com = 0;
56 while (!IsDevicePathEnd (Node)) {
57 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
58 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
59 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
60 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
61 }
62 }
63
64 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);
65 if (NULL == NewMenuEntry) {
66 return EFI_NOT_FOUND;
67 }
68
69 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
70 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
71 Uart = (UART_DEVICE_PATH *) Node;
72 CopyMem (
73 &Uart->BaudRate,
74 &NewTerminalContext->BaudRate,
75 sizeof (UINT64)
76 );
77
78 CopyMem (
79 &Uart->DataBits,
80 &NewTerminalContext->DataBits,
81 sizeof (UINT8)
82 );
83
84 CopyMem (
85 &Uart->Parity,
86 &NewTerminalContext->Parity,
87 sizeof (UINT8)
88 );
89
90 CopyMem (
91 &Uart->StopBits,
92 &NewTerminalContext->StopBits,
93 sizeof (UINT8)
94 );
95 //
96 // Change the device path in the ComPort
97 //
98 if (ChangeTerminal) {
99 Node1 = NewTerminalContext->DevicePath;
100 Node1 = NextDevicePathNode (Node1);
101 while (!IsDevicePathEnd (Node1)) {
102 if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {
103 Uart1 = (UART_DEVICE_PATH *) Node1;
104 CopyMem (
105 &Uart1->BaudRate,
106 &NewTerminalContext->BaudRate,
107 sizeof (UINT64)
108 );
109
110 CopyMem (
111 &Uart1->DataBits,
112 &NewTerminalContext->DataBits,
113 sizeof (UINT8)
114 );
115
116 CopyMem (
117 &Uart1->Parity,
118 &NewTerminalContext->Parity,
119 sizeof (UINT8)
120 );
121
122 CopyMem (
123 &Uart1->StopBits,
124 &NewTerminalContext->StopBits,
125 sizeof (UINT8)
126 );
127 break;
128 }
129 //
130 // end if
131 //
132 Node1 = NextDevicePathNode (Node1);
133 }
134 //
135 // end while
136 //
137 break;
138 }
139 }
140
141 Node = NextDevicePathNode (Node);
142 }
143
144 return EFI_SUCCESS;
145
146 }
147
148 VOID
149 ChangeVariableDevicePath (
150 EFI_DEVICE_PATH_PROTOCOL *DevicePath
151 )
152 {
153 EFI_DEVICE_PATH_PROTOCOL *Node;
154 ACPI_HID_DEVICE_PATH *Acpi;
155 UART_DEVICE_PATH *Uart;
156 UINTN Com;
157 UINT32 Match;
158 BM_TERMINAL_CONTEXT *NewTerminalContext;
159 BM_MENU_ENTRY *NewMenuEntry;
160
161 Match = EISA_PNP_ID (0x0501);
162 Node = DevicePath;
163 Node = NextDevicePathNode (Node);
164 Com = 0;
165 while (!IsDevicePathEnd (Node)) {
166 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
167 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
168 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
169 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));
170 }
171 }
172
173 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
174 NewMenuEntry = BOpt_GetMenuEntry (
175 &TerminalMenu,
176 Com
177 );
178 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
179 Uart = (UART_DEVICE_PATH *) Node;
180 CopyMem (
181 &Uart->BaudRate,
182 &NewTerminalContext->BaudRate,
183 sizeof (UINT64)
184 );
185
186 CopyMem (
187 &Uart->DataBits,
188 &NewTerminalContext->DataBits,
189 sizeof (UINT8)
190 );
191
192 CopyMem (
193 &Uart->Parity,
194 &NewTerminalContext->Parity,
195 sizeof (UINT8)
196 );
197
198 CopyMem (
199 &Uart->StopBits,
200 &NewTerminalContext->StopBits,
201 sizeof (UINT8)
202 );
203 }
204
205 Node = NextDevicePathNode (Node);
206 }
207
208 return ;
209 }
210
211 BOOLEAN
212 IsTerminalDevicePath (
213 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
214 OUT TYPE_OF_TERMINAL *Termi,
215 OUT UINTN *Com
216 );
217
218 EFI_STATUS
219 LocateSerialIo (
220 VOID
221 )
222 /*++
223
224 Routine Description:
225 Build a list containing all serial devices
226
227 Arguments:
228
229 Returns:
230
231 --*/
232 {
233 UINT8 *Ptr;
234 UINTN Index;
235 UINTN Index2;
236 UINTN NoHandles;
237 EFI_HANDLE *Handles;
238 EFI_STATUS Status;
239 ACPI_HID_DEVICE_PATH *Acpi;
240 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
241 UINT32 Match;
242 EFI_SERIAL_IO_PROTOCOL *SerialIo;
243 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
244 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
245 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
246 BM_MENU_ENTRY *NewMenuEntry;
247 BM_TERMINAL_CONTEXT *NewTerminalContext;
248 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
249 VENDOR_DEVICE_PATH Vendor;
250 //
251 // Get all handles that have SerialIo protocol installed
252 //
253 InitializeListHead (&TerminalMenu.Head);
254 TerminalMenu.MenuNumber = 0;
255 Status = gBS->LocateHandleBuffer (
256 ByProtocol,
257 &gEfiSerialIoProtocolGuid,
258 NULL,
259 &NoHandles,
260 &Handles
261 );
262 if (EFI_ERROR (Status)) {
263 //
264 // No serial ports present
265 //
266 return EFI_UNSUPPORTED;
267 }
268
269 for (Index = 0; Index < NoHandles; Index++) {
270 //
271 // Check to see whether the handle has DevicePath Protocol installed
272 //
273 gBS->HandleProtocol (
274 Handles[Index],
275 &gEfiDevicePathProtocolGuid,
276 &DevicePath
277 );
278 Ptr = (UINT8 *) DevicePath;
279 while (*Ptr != END_DEVICE_PATH_TYPE) {
280 Ptr++;
281 }
282
283 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
284 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
285 Match = EISA_PNP_ID (0x0501);
286
287 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
288 NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
289 if (!NewMenuEntry) {
290 return EFI_OUT_OF_RESOURCES;
291 }
292
293 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
294 CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
295 NewTerminalContext->DevicePath = DevicePathInstanceDup (DevicePath);
296 //
297 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
298 // coz' the misc data for each platform is not correct, actually it's the device path stored in
299 // datahub which is not completed, so a searching for end of device path will enter a
300 // dead-loop.
301 //
302 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
303 if (NULL == NewMenuEntry->DisplayString) {
304 NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);
305 }
306
307 NewMenuEntry->HelpString = NULL;
308
309 gBS->HandleProtocol (
310 Handles[Index],
311 &gEfiSerialIoProtocolGuid,
312 &SerialIo
313 );
314
315 CopyMem (
316 &NewTerminalContext->BaudRate,
317 &SerialIo->Mode->BaudRate,
318 sizeof (UINT64)
319 );
320
321 CopyMem (
322 &NewTerminalContext->DataBits,
323 &SerialIo->Mode->DataBits,
324 sizeof (UINT8)
325 );
326
327 CopyMem (
328 &NewTerminalContext->Parity,
329 &SerialIo->Mode->Parity,
330 sizeof (UINT8)
331 );
332
333 CopyMem (
334 &NewTerminalContext->StopBits,
335 &SerialIo->Mode->StopBits,
336 sizeof (UINT8)
337 );
338 InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
339 TerminalMenu.MenuNumber++;
340 }
341 }
342 //
343 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
344 //
345 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
346 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
347 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
348 if (OutDevicePath) {
349 UpdateComAttributeFromVariable (OutDevicePath);
350 }
351
352 if (InpDevicePath) {
353 UpdateComAttributeFromVariable (InpDevicePath);
354 }
355
356 if (ErrDevicePath) {
357 UpdateComAttributeFromVariable (ErrDevicePath);
358 }
359
360 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
361 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
362 if (NULL == NewMenuEntry) {
363 return EFI_NOT_FOUND;
364 }
365
366 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
367
368 NewTerminalContext->TerminalType = 0;
369 NewTerminalContext->IsConIn = FALSE;
370 NewTerminalContext->IsConOut = FALSE;
371 NewTerminalContext->IsStdErr = FALSE;
372
373 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
374 Vendor.Header.SubType = MSG_VENDOR_DP;
375
376 for (Index2 = 0; Index2 < 4; Index2++) {
377 CopyMem (&Vendor.Guid, &Guid[Index2], sizeof (EFI_GUID));
378 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
379 NewDevicePath = AppendDevicePathNode (
380 NewTerminalContext->DevicePath,
381 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
382 );
383 SafeFreePool (NewMenuEntry->HelpString);
384 //
385 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
386 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
387 //
388 NewMenuEntry->HelpString = NULL;
389
390 if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {
391 NewTerminalContext->IsConOut = TRUE;
392 NewTerminalContext->TerminalType = (UINT8) Index2;
393 }
394
395 if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {
396 NewTerminalContext->IsConIn = TRUE;
397 NewTerminalContext->TerminalType = (UINT8) Index2;
398 }
399
400 if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {
401 NewTerminalContext->IsStdErr = TRUE;
402 NewTerminalContext->TerminalType = (UINT8) Index2;
403 }
404 }
405 }
406
407 return EFI_SUCCESS;
408 }
409
410 EFI_STATUS
411 UpdateComAttributeFromVariable (
412 EFI_DEVICE_PATH_PROTOCOL *DevicePath
413 )
414 /*++
415
416 Routine Description:
417 Update Com Ports attributes from DevicePath
418
419 Arguments:
420 DevicePath - DevicePath that contains Com ports
421
422 Returns:
423
424 --*/
425 {
426 EFI_DEVICE_PATH_PROTOCOL *Node;
427 EFI_DEVICE_PATH_PROTOCOL *SerialNode;
428 ACPI_HID_DEVICE_PATH *Acpi;
429 UART_DEVICE_PATH *Uart;
430 UART_DEVICE_PATH *Uart1;
431 UINT32 Match;
432 UINTN TerminalNumber;
433 BM_MENU_ENTRY *NewMenuEntry;
434 BM_TERMINAL_CONTEXT *NewTerminalContext;
435 UINTN Index;
436
437 Match = EISA_PNP_ID (0x0501);
438 Node = DevicePath;
439 Node = NextDevicePathNode (Node);
440 TerminalNumber = 0;
441 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
442 while (!IsDevicePathEnd (Node)) {
443 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
444 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
445 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
446 CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));
447 }
448 }
449
450 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
451 Uart = (UART_DEVICE_PATH *) Node;
452 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);
453 if (NULL == NewMenuEntry) {
454 return EFI_NOT_FOUND;
455 }
456
457 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
458 CopyMem (
459 &NewTerminalContext->BaudRate,
460 &Uart->BaudRate,
461 sizeof (UINT64)
462 );
463
464 CopyMem (
465 &NewTerminalContext->DataBits,
466 &Uart->DataBits,
467 sizeof (UINT8)
468 );
469
470 CopyMem (
471 &NewTerminalContext->Parity,
472 &Uart->Parity,
473 sizeof (UINT8)
474 );
475
476 CopyMem (
477 &NewTerminalContext->StopBits,
478 &Uart->StopBits,
479 sizeof (UINT8)
480 );
481
482 SerialNode = NewTerminalContext->DevicePath;
483 SerialNode = NextDevicePathNode (SerialNode);
484 while (!IsDevicePathEnd (SerialNode)) {
485 if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {
486 //
487 // Update following device paths according to
488 // previous acquired uart attributes
489 //
490 Uart1 = (UART_DEVICE_PATH *) SerialNode;
491 CopyMem (
492 &Uart1->BaudRate,
493 &NewTerminalContext->BaudRate,
494 sizeof (UINT64)
495 );
496
497 CopyMem (
498 &Uart1->DataBits,
499 &NewTerminalContext->DataBits,
500 sizeof (UINT8)
501 );
502 CopyMem (
503 &Uart1->Parity,
504 &NewTerminalContext->Parity,
505 sizeof (UINT8)
506 );
507 CopyMem (
508 &Uart1->StopBits,
509 &NewTerminalContext->StopBits,
510 sizeof (UINT8)
511 );
512
513 break;
514 }
515
516 SerialNode = NextDevicePathNode (SerialNode);
517 }
518 //
519 // end while
520 //
521 }
522
523 Node = NextDevicePathNode (Node);
524 }
525 //
526 // end while
527 //
528 }
529
530 return EFI_SUCCESS;
531 }
532
533 EFI_DEVICE_PATH_PROTOCOL *
534 DevicePathInstanceDup (
535 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
536 )
537 /*++
538
539 Routine Description:
540 Function creates a device path data structure that identically matches the
541 device path passed in.
542
543 Arguments:
544 DevPath - A pointer to a device path data structure.
545
546 Returns:
547
548 The new copy of DevPath is created to identically match the input.
549 Otherwise, NULL is returned.
550
551 --*/
552 {
553 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
554 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
555 EFI_DEVICE_PATH_PROTOCOL *Temp;
556 UINT8 *Ptr;
557 UINTN Size;
558
559 //
560 // get the size of an instance from the input
561 //
562 Temp = DevPath;
563 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
564
565 //
566 // Make a copy and set proper end type
567 //
568 NewDevPath = NULL;
569 if (Size) {
570 NewDevPath = AllocateZeroPool (Size);
571 ASSERT (NewDevPath != NULL);
572 }
573
574 if (NewDevPath) {
575 CopyMem (NewDevPath, DevicePathInst, Size);
576 Ptr = (UINT8 *) NewDevPath;
577 Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);
578 Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
579 SetDevicePathEndNode (Temp);
580 }
581
582 return NewDevPath;
583 }
584
585 EFI_STATUS
586 GetConsoleMenu (
587 IN UINTN ConsoleMenuType
588 )
589 {
590 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
591 EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;
592 EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;
593 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
594 UINTN Size;
595 UINTN AllCount;
596 UINTN Index;
597 UINTN Index2;
598 BM_MENU_ENTRY *NewMenuEntry;
599 BM_CONSOLE_CONTEXT *NewConsoleContext;
600 BM_TERMINAL_CONTEXT *NewTerminalContext;
601 TYPE_OF_TERMINAL Terminal;
602 BM_MENU_ENTRY *NewTerminalMenuEntry;
603 UINTN Com;
604 BM_MENU_OPTION *ConsoleMenu;
605
606 DevicePath = NULL;
607 AllDevicePath = NULL;
608 AllCount = 0;
609 switch (ConsoleMenuType) {
610 case BM_CONSOLE_IN_CONTEXT_SELECT:
611 ConsoleMenu = &ConsoleInpMenu;
612 DevicePath = EfiLibGetVariable (
613 L"ConIn",
614 &gEfiGlobalVariableGuid
615 );
616
617 AllDevicePath = EfiLibGetVariable (
618 L"ConInDev",
619 &gEfiGlobalVariableGuid
620 );
621 break;
622
623 case BM_CONSOLE_OUT_CONTEXT_SELECT:
624 ConsoleMenu = &ConsoleOutMenu;
625 DevicePath = EfiLibGetVariable (
626 L"ConOut",
627 &gEfiGlobalVariableGuid
628 );
629
630 AllDevicePath = EfiLibGetVariable (
631 L"ConOutDev",
632 &gEfiGlobalVariableGuid
633 );
634 break;
635
636 case BM_CONSOLE_ERR_CONTEXT_SELECT:
637 ConsoleMenu = &ConsoleErrMenu;
638 DevicePath = EfiLibGetVariable (
639 L"ErrOut",
640 &gEfiGlobalVariableGuid
641 );
642
643 AllDevicePath = EfiLibGetVariable (
644 L"ErrOutDev",
645 &gEfiGlobalVariableGuid
646 );
647 break;
648
649 default:
650 return EFI_UNSUPPORTED;
651 }
652
653 if (NULL == AllDevicePath) {
654 return EFI_NOT_FOUND;
655 }
656
657 InitializeListHead (&ConsoleMenu->Head);
658
659 AllCount = EfiDevicePathInstanceCount (AllDevicePath);
660 ConsoleMenu->MenuNumber = 0;
661 //
662 // Following is menu building up for Console Out Devices
663 //
664 MultiDevicePath = AllDevicePath;
665 Index2 = 0;
666 for (Index = 0; Index < AllCount; Index++) {
667 DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);
668
669 NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
670 if (NULL == NewMenuEntry) {
671 return EFI_OUT_OF_RESOURCES;
672 }
673
674 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
675 NewMenuEntry->OptionNumber = Index2;
676
677 NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst);
678 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
679 if (NULL == NewMenuEntry->DisplayString) {
680 NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);
681 }
682
683 NewConsoleContext->IsTerminal = IsTerminalDevicePath (
684 NewConsoleContext->DevicePath,
685 &Terminal,
686 &Com
687 );
688
689 NewConsoleContext->IsActive = BdsLibMatchDevicePaths (
690 DevicePath,
691 NewConsoleContext->DevicePath
692 );
693 NewTerminalMenuEntry = NULL;
694 NewTerminalContext = NULL;
695
696 if (NewConsoleContext->IsTerminal) {
697 BOpt_DestroyMenuEntry (NewMenuEntry);
698 } else {
699 Index2++;
700 ConsoleMenu->MenuNumber++;
701 InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
702 }
703 }
704
705 return EFI_SUCCESS;
706 }
707
708 EFI_STATUS
709 GetAllConsoles (
710 VOID
711 )
712 /*++
713
714 Routine Description:
715 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
716
717 Arguments:
718
719 Returns:
720 EFI_SUCCESS
721 Others
722
723 --*/
724 {
725 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
726 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
727 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
728 return EFI_SUCCESS;
729 }
730
731 EFI_STATUS
732 FreeAllConsoles (
733 VOID
734 )
735 /*++
736
737 Routine Description:
738 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
739
740 Arguments:
741
742 Returns:
743 EFI_SUCCESS
744 Others
745
746 --*/
747 {
748 BOpt_FreeMenu (&ConsoleOutMenu);
749 BOpt_FreeMenu (&ConsoleInpMenu);
750 BOpt_FreeMenu (&ConsoleErrMenu);
751 BOpt_FreeMenu (&TerminalMenu);
752 return EFI_SUCCESS;
753 }
754
755 BOOLEAN
756 IsTerminalDevicePath (
757 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
758 OUT TYPE_OF_TERMINAL *Termi,
759 OUT UINTN *Com
760 )
761 /*++
762
763 Routine Description:
764 Test whether DevicePath is a valid Terminal
765
766 Arguments:
767 DevicePath - DevicePath to be checked
768 Termi - If is terminal, give its type
769 Com - If is Com Port, give its type
770
771 Returns:
772 TRUE - If DevicePath point to a Terminal
773 FALSE
774
775 --*/
776 {
777 UINT8 *Ptr;
778 BOOLEAN IsTerminal;
779 VENDOR_DEVICE_PATH *Vendor;
780 ACPI_HID_DEVICE_PATH *Acpi;
781 UINT32 Match;
782 EFI_GUID TempGuid;
783
784 IsTerminal = FALSE;
785
786 //
787 // Parse the Device Path, should be change later!!!
788 //
789 Ptr = (UINT8 *) DevicePath;
790 while (*Ptr != END_DEVICE_PATH_TYPE) {
791 Ptr++;
792 }
793
794 Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH);
795 Vendor = (VENDOR_DEVICE_PATH *) Ptr;
796
797 //
798 // There are four kinds of Terminal types
799 // check to see whether this devicepath
800 // is one of that type
801 //
802 CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));
803
804 if (CompareGuid (&TempGuid, &Guid[0])) {
805 *Termi = PC_ANSI;
806 IsTerminal = TRUE;
807 } else {
808 if (CompareGuid (&TempGuid, &Guid[1])) {
809 *Termi = VT_100;
810 IsTerminal = TRUE;
811 } else {
812 if (CompareGuid (&TempGuid, &Guid[2])) {
813 *Termi = VT_100_PLUS;
814 IsTerminal = TRUE;
815 } else {
816 if (CompareGuid (&TempGuid, &Guid[3])) {
817 *Termi = VT_UTF8;
818 IsTerminal = TRUE;
819 } else {
820 IsTerminal = FALSE;
821 }
822 }
823 }
824 }
825
826 if (!IsTerminal) {
827 return FALSE;
828 }
829
830 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
831 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
832 Match = EISA_PNP_ID (0x0501);
833 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
834 CopyMem (Com, &Acpi->UID, sizeof (UINT32));
835 } else {
836 return FALSE;
837 }
838
839 return TRUE;
840 }