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