]> git.proxmox.com Git - mirror_edk2.git/blob - EdkUnixPkg/Dxe/PlatformBds/Generic/BootMaint/ConsoleOption.c
9acacc8e72087d470df6a94c2a441f6999f1fe78
[mirror_edk2.git] / EdkUnixPkg / 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 ASSERT (NewMenuEntry != NULL);
179 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
180 Uart = (UART_DEVICE_PATH *) Node;
181 CopyMem (
182 &Uart->BaudRate,
183 &NewTerminalContext->BaudRate,
184 sizeof (UINT64)
185 );
186
187 CopyMem (
188 &Uart->DataBits,
189 &NewTerminalContext->DataBits,
190 sizeof (UINT8)
191 );
192
193 CopyMem (
194 &Uart->Parity,
195 &NewTerminalContext->Parity,
196 sizeof (UINT8)
197 );
198
199 CopyMem (
200 &Uart->StopBits,
201 &NewTerminalContext->StopBits,
202 sizeof (UINT8)
203 );
204 }
205
206 Node = NextDevicePathNode (Node);
207 }
208
209 return ;
210 }
211
212 BOOLEAN
213 IsTerminalDevicePath (
214 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
215 OUT TYPE_OF_TERMINAL *Termi,
216 OUT UINTN *Com
217 );
218
219 EFI_STATUS
220 LocateSerialIo (
221 VOID
222 )
223 /*++
224
225 Routine Description:
226 Build a list containing all serial devices
227
228 Arguments:
229
230 Returns:
231
232 --*/
233 {
234 UINT8 *Ptr;
235 UINTN Index;
236 UINTN Index2;
237 UINTN NoHandles;
238 EFI_HANDLE *Handles;
239 EFI_STATUS Status;
240 ACPI_HID_DEVICE_PATH *Acpi;
241 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
242 UINT32 Match;
243 EFI_SERIAL_IO_PROTOCOL *SerialIo;
244 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
245 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
246 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
247 BM_MENU_ENTRY *NewMenuEntry;
248 BM_TERMINAL_CONTEXT *NewTerminalContext;
249 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
250 VENDOR_DEVICE_PATH Vendor;
251 //
252 // Get all handles that have SerialIo protocol installed
253 //
254 InitializeListHead (&TerminalMenu.Head);
255 TerminalMenu.MenuNumber = 0;
256 Status = gBS->LocateHandleBuffer (
257 ByProtocol,
258 &gEfiSerialIoProtocolGuid,
259 NULL,
260 &NoHandles,
261 &Handles
262 );
263 if (EFI_ERROR (Status)) {
264 //
265 // No serial ports present
266 //
267 return EFI_UNSUPPORTED;
268 }
269
270 for (Index = 0; Index < NoHandles; Index++) {
271 //
272 // Check to see whether the handle has DevicePath Protocol installed
273 //
274 gBS->HandleProtocol (
275 Handles[Index],
276 &gEfiDevicePathProtocolGuid,
277 (VOID**) &DevicePath
278 );
279 Ptr = (UINT8 *) DevicePath;
280 while (*Ptr != END_DEVICE_PATH_TYPE) {
281 Ptr++;
282 }
283
284 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
285 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
286 Match = EISA_PNP_ID (0x0501);
287
288 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
289 NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
290 if (!NewMenuEntry) {
291 return EFI_OUT_OF_RESOURCES;
292 }
293
294 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
295 CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
296 NewTerminalContext->DevicePath = DevicePathInstanceDup (DevicePath);
297 //
298 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
299 // coz' the misc data for each platform is not correct, actually it's the device path stored in
300 // datahub which is not completed, so a searching for end of device path will enter a
301 // dead-loop.
302 //
303 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
304 if (NULL == NewMenuEntry->DisplayString) {
305 NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);
306 }
307
308 NewMenuEntry->HelpString = NULL;
309
310 gBS->HandleProtocol (
311 Handles[Index],
312 &gEfiSerialIoProtocolGuid,
313 (VOID**) &SerialIo
314 );
315
316 CopyMem (
317 &NewTerminalContext->BaudRate,
318 &SerialIo->Mode->BaudRate,
319 sizeof (UINT64)
320 );
321
322 CopyMem (
323 &NewTerminalContext->DataBits,
324 &SerialIo->Mode->DataBits,
325 sizeof (UINT8)
326 );
327
328 CopyMem (
329 &NewTerminalContext->Parity,
330 &SerialIo->Mode->Parity,
331 sizeof (UINT8)
332 );
333
334 CopyMem (
335 &NewTerminalContext->StopBits,
336 &SerialIo->Mode->StopBits,
337 sizeof (UINT8)
338 );
339 InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
340 TerminalMenu.MenuNumber++;
341 }
342 }
343 //
344 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
345 //
346 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
347 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
348 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
349 if (OutDevicePath) {
350 UpdateComAttributeFromVariable (OutDevicePath);
351 }
352
353 if (InpDevicePath) {
354 UpdateComAttributeFromVariable (InpDevicePath);
355 }
356
357 if (ErrDevicePath) {
358 UpdateComAttributeFromVariable (ErrDevicePath);
359 }
360
361 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
362 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
363 if (NULL == NewMenuEntry) {
364 return EFI_NOT_FOUND;
365 }
366
367 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
368
369 NewTerminalContext->TerminalType = 0;
370 NewTerminalContext->IsConIn = FALSE;
371 NewTerminalContext->IsConOut = FALSE;
372 NewTerminalContext->IsStdErr = FALSE;
373
374 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
375 Vendor.Header.SubType = MSG_VENDOR_DP;
376
377 for (Index2 = 0; Index2 < 4; Index2++) {
378 CopyMem (&Vendor.Guid, &Guid[Index2], sizeof (EFI_GUID));
379 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
380 NewDevicePath = AppendDevicePathNode (
381 NewTerminalContext->DevicePath,
382 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
383 );
384 SafeFreePool (NewMenuEntry->HelpString);
385 //
386 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
387 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
388 //
389 NewMenuEntry->HelpString = NULL;
390
391 if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {
392 NewTerminalContext->IsConOut = TRUE;
393 NewTerminalContext->TerminalType = (UINT8) Index2;
394 }
395
396 if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {
397 NewTerminalContext->IsConIn = TRUE;
398 NewTerminalContext->TerminalType = (UINT8) Index2;
399 }
400
401 if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {
402 NewTerminalContext->IsStdErr = TRUE;
403 NewTerminalContext->TerminalType = (UINT8) Index2;
404 }
405 }
406 }
407
408 return EFI_SUCCESS;
409 }
410
411 EFI_STATUS
412 UpdateComAttributeFromVariable (
413 EFI_DEVICE_PATH_PROTOCOL *DevicePath
414 )
415 /*++
416
417 Routine Description:
418 Update Com Ports attributes from DevicePath
419
420 Arguments:
421 DevicePath - DevicePath that contains Com ports
422
423 Returns:
424
425 --*/
426 {
427 EFI_DEVICE_PATH_PROTOCOL *Node;
428 EFI_DEVICE_PATH_PROTOCOL *SerialNode;
429 ACPI_HID_DEVICE_PATH *Acpi;
430 UART_DEVICE_PATH *Uart;
431 UART_DEVICE_PATH *Uart1;
432 UINT32 Match;
433 UINTN TerminalNumber;
434 BM_MENU_ENTRY *NewMenuEntry;
435 BM_TERMINAL_CONTEXT *NewTerminalContext;
436 UINTN Index;
437
438 Match = EISA_PNP_ID (0x0501);
439 Node = DevicePath;
440 Node = NextDevicePathNode (Node);
441 TerminalNumber = 0;
442 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
443 while (!IsDevicePathEnd (Node)) {
444 if ((DevicePathType (Node) == ACPI_DEVICE_PATH) && (DevicePathSubType (Node) == ACPI_DP)) {
445 Acpi = (ACPI_HID_DEVICE_PATH *) Node;
446 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
447 CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));
448 }
449 }
450
451 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
452 Uart = (UART_DEVICE_PATH *) Node;
453 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);
454 if (NULL == NewMenuEntry) {
455 return EFI_NOT_FOUND;
456 }
457
458 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
459 CopyMem (
460 &NewTerminalContext->BaudRate,
461 &Uart->BaudRate,
462 sizeof (UINT64)
463 );
464
465 CopyMem (
466 &NewTerminalContext->DataBits,
467 &Uart->DataBits,
468 sizeof (UINT8)
469 );
470
471 CopyMem (
472 &NewTerminalContext->Parity,
473 &Uart->Parity,
474 sizeof (UINT8)
475 );
476
477 CopyMem (
478 &NewTerminalContext->StopBits,
479 &Uart->StopBits,
480 sizeof (UINT8)
481 );
482
483 SerialNode = NewTerminalContext->DevicePath;
484 SerialNode = NextDevicePathNode (SerialNode);
485 while (!IsDevicePathEnd (SerialNode)) {
486 if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {
487 //
488 // Update following device paths according to
489 // previous acquired uart attributes
490 //
491 Uart1 = (UART_DEVICE_PATH *) SerialNode;
492 CopyMem (
493 &Uart1->BaudRate,
494 &NewTerminalContext->BaudRate,
495 sizeof (UINT64)
496 );
497
498 CopyMem (
499 &Uart1->DataBits,
500 &NewTerminalContext->DataBits,
501 sizeof (UINT8)
502 );
503 CopyMem (
504 &Uart1->Parity,
505 &NewTerminalContext->Parity,
506 sizeof (UINT8)
507 );
508 CopyMem (
509 &Uart1->StopBits,
510 &NewTerminalContext->StopBits,
511 sizeof (UINT8)
512 );
513
514 break;
515 }
516
517 SerialNode = NextDevicePathNode (SerialNode);
518 }
519 //
520 // end while
521 //
522 }
523
524 Node = NextDevicePathNode (Node);
525 }
526 //
527 // end while
528 //
529 }
530
531 return EFI_SUCCESS;
532 }
533
534 EFI_DEVICE_PATH_PROTOCOL *
535 DevicePathInstanceDup (
536 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
537 )
538 /*++
539
540 Routine Description:
541 Function creates a device path data structure that identically matches the
542 device path passed in.
543
544 Arguments:
545 DevPath - A pointer to a device path data structure.
546
547 Returns:
548
549 The new copy of DevPath is created to identically match the input.
550 Otherwise, NULL is returned.
551
552 --*/
553 {
554 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
555 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
556 EFI_DEVICE_PATH_PROTOCOL *Temp;
557 UINT8 *Ptr;
558 UINTN Size;
559
560 //
561 // get the size of an instance from the input
562 //
563 Temp = DevPath;
564 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
565
566 //
567 // Make a copy and set proper end type
568 //
569 NewDevPath = NULL;
570 if (Size) {
571 NewDevPath = AllocateZeroPool (Size);
572 ASSERT (NewDevPath != NULL);
573 }
574
575 if (NewDevPath) {
576 CopyMem (NewDevPath, DevicePathInst, Size);
577 Ptr = (UINT8 *) NewDevPath;
578 Ptr += Size - sizeof (EFI_DEVICE_PATH_PROTOCOL);
579 Temp = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
580 SetDevicePathEndNode (Temp);
581 }
582
583 return NewDevPath;
584 }
585
586 EFI_STATUS
587 GetConsoleMenu (
588 IN UINTN ConsoleMenuType
589 )
590 {
591 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
592 EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;
593 EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;
594 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
595 UINTN Size;
596 UINTN AllCount;
597 UINTN Index;
598 UINTN Index2;
599 BM_MENU_ENTRY *NewMenuEntry;
600 BM_CONSOLE_CONTEXT *NewConsoleContext;
601 BM_TERMINAL_CONTEXT *NewTerminalContext;
602 TYPE_OF_TERMINAL Terminal;
603 BM_MENU_ENTRY *NewTerminalMenuEntry;
604 UINTN Com;
605 BM_MENU_OPTION *ConsoleMenu;
606
607 DevicePath = NULL;
608 AllDevicePath = NULL;
609 AllCount = 0;
610 switch (ConsoleMenuType) {
611 case BM_CONSOLE_IN_CONTEXT_SELECT:
612 ConsoleMenu = &ConsoleInpMenu;
613 DevicePath = EfiLibGetVariable (
614 L"ConIn",
615 &gEfiGlobalVariableGuid
616 );
617
618 AllDevicePath = EfiLibGetVariable (
619 L"ConInDev",
620 &gEfiGlobalVariableGuid
621 );
622 break;
623
624 case BM_CONSOLE_OUT_CONTEXT_SELECT:
625 ConsoleMenu = &ConsoleOutMenu;
626 DevicePath = EfiLibGetVariable (
627 L"ConOut",
628 &gEfiGlobalVariableGuid
629 );
630
631 AllDevicePath = EfiLibGetVariable (
632 L"ConOutDev",
633 &gEfiGlobalVariableGuid
634 );
635 break;
636
637 case BM_CONSOLE_ERR_CONTEXT_SELECT:
638 ConsoleMenu = &ConsoleErrMenu;
639 DevicePath = EfiLibGetVariable (
640 L"ErrOut",
641 &gEfiGlobalVariableGuid
642 );
643
644 AllDevicePath = EfiLibGetVariable (
645 L"ErrOutDev",
646 &gEfiGlobalVariableGuid
647 );
648 break;
649
650 default:
651 return EFI_UNSUPPORTED;
652 }
653
654 if (NULL == AllDevicePath) {
655 return EFI_NOT_FOUND;
656 }
657
658 InitializeListHead (&ConsoleMenu->Head);
659
660 AllCount = EfiDevicePathInstanceCount (AllDevicePath);
661 ConsoleMenu->MenuNumber = 0;
662 //
663 // Following is menu building up for Console Out Devices
664 //
665 MultiDevicePath = AllDevicePath;
666 Index2 = 0;
667 for (Index = 0; Index < AllCount; Index++) {
668 DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);
669
670 NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
671 if (NULL == NewMenuEntry) {
672 return EFI_OUT_OF_RESOURCES;
673 }
674
675 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
676 NewMenuEntry->OptionNumber = Index2;
677
678 NewConsoleContext->DevicePath = DevicePathInstanceDup (DevicePathInst);
679 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
680 if (NULL == NewMenuEntry->DisplayString) {
681 NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);
682 }
683
684 NewConsoleContext->IsTerminal = IsTerminalDevicePath (
685 NewConsoleContext->DevicePath,
686 &Terminal,
687 &Com
688 );
689
690 NewConsoleContext->IsActive = BdsLibMatchDevicePaths (
691 DevicePath,
692 NewConsoleContext->DevicePath
693 );
694 NewTerminalMenuEntry = NULL;
695 NewTerminalContext = NULL;
696
697 if (NewConsoleContext->IsTerminal) {
698 BOpt_DestroyMenuEntry (NewMenuEntry);
699 } else {
700 Index2++;
701 ConsoleMenu->MenuNumber++;
702 InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
703 }
704 }
705
706 return EFI_SUCCESS;
707 }
708
709 EFI_STATUS
710 GetAllConsoles (
711 VOID
712 )
713 /*++
714
715 Routine Description:
716 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
717
718 Arguments:
719
720 Returns:
721 EFI_SUCCESS
722 Others
723
724 --*/
725 {
726 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);
727 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);
728 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);
729 return EFI_SUCCESS;
730 }
731
732 EFI_STATUS
733 FreeAllConsoles (
734 VOID
735 )
736 /*++
737
738 Routine Description:
739 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu
740
741 Arguments:
742
743 Returns:
744 EFI_SUCCESS
745 Others
746
747 --*/
748 {
749 BOpt_FreeMenu (&ConsoleOutMenu);
750 BOpt_FreeMenu (&ConsoleInpMenu);
751 BOpt_FreeMenu (&ConsoleErrMenu);
752 BOpt_FreeMenu (&TerminalMenu);
753 return EFI_SUCCESS;
754 }
755
756 BOOLEAN
757 IsTerminalDevicePath (
758 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
759 OUT TYPE_OF_TERMINAL *Termi,
760 OUT UINTN *Com
761 )
762 /*++
763
764 Routine Description:
765 Test whether DevicePath is a valid Terminal
766
767 Arguments:
768 DevicePath - DevicePath to be checked
769 Termi - If is terminal, give its type
770 Com - If is Com Port, give its type
771
772 Returns:
773 TRUE - If DevicePath point to a Terminal
774 FALSE
775
776 --*/
777 {
778 UINT8 *Ptr;
779 BOOLEAN IsTerminal;
780 VENDOR_DEVICE_PATH *Vendor;
781 ACPI_HID_DEVICE_PATH *Acpi;
782 UINT32 Match;
783 EFI_GUID TempGuid;
784
785 IsTerminal = FALSE;
786
787 //
788 // Parse the Device Path, should be change later!!!
789 //
790 Ptr = (UINT8 *) DevicePath;
791 while (*Ptr != END_DEVICE_PATH_TYPE) {
792 Ptr++;
793 }
794
795 Ptr = Ptr - sizeof (VENDOR_DEVICE_PATH);
796 Vendor = (VENDOR_DEVICE_PATH *) Ptr;
797
798 //
799 // There are four kinds of Terminal types
800 // check to see whether this devicepath
801 // is one of that type
802 //
803 CopyMem (&TempGuid, &Vendor->Guid, sizeof (EFI_GUID));
804
805 if (CompareGuid (&TempGuid, &Guid[0])) {
806 *Termi = PC_ANSI;
807 IsTerminal = TRUE;
808 } else {
809 if (CompareGuid (&TempGuid, &Guid[1])) {
810 *Termi = VT_100;
811 IsTerminal = TRUE;
812 } else {
813 if (CompareGuid (&TempGuid, &Guid[2])) {
814 *Termi = VT_100_PLUS;
815 IsTerminal = TRUE;
816 } else {
817 if (CompareGuid (&TempGuid, &Guid[3])) {
818 *Termi = VT_UTF8;
819 IsTerminal = TRUE;
820 } else {
821 IsTerminal = FALSE;
822 }
823 }
824 }
825 }
826
827 if (!IsTerminal) {
828 return FALSE;
829 }
830
831 Ptr = Ptr - sizeof (UART_DEVICE_PATH) - sizeof (ACPI_HID_DEVICE_PATH);
832 Acpi = (ACPI_HID_DEVICE_PATH *) Ptr;
833 Match = EISA_PNP_ID (0x0501);
834 if (CompareMem (&Acpi->HID, &Match, sizeof (UINT32)) == 0) {
835 CopyMem (Com, &Acpi->UID, sizeof (UINT32));
836 } else {
837 return FALSE;
838 }
839
840 return TRUE;
841 }