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