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