]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/ConsoleOption.c
IntelFrameworkModulePkg/BdsDxe: rebase to ARRAY_SIZE()
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / ConsoleOption.c
CommitLineData
5c08e117 1/** @file\r
2 handles console redirection from boot manager\r
3\r
be9304f3 4Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 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
13**/\r
14\r
15#include "BootMaint.h"\r
16\r
ce68d3bc
SZ
17UART_FLOW_CONTROL_DEVICE_PATH mFlowControlDevicePath =\r
18{\r
19 {\r
20 MESSAGING_DEVICE_PATH,\r
21 MSG_VENDOR_DP,\r
22 {\r
23 (UINT8)(sizeof(UART_FLOW_CONTROL_DEVICE_PATH)),\r
24 (UINT8)((sizeof(UART_FLOW_CONTROL_DEVICE_PATH)) >> 8)\r
25 }\r
26 },\r
8e491a81
ED
27 DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL,\r
28 UART_FLOW_CONTROL_HARDWARE\r
29};\r
30\r
31/**\r
32 Check the device path node whether it's the Flow Control node or not.\r
33\r
34 @param[in] FlowControl The device path node to be checked.\r
35 \r
36 @retval TRUE It's the Flow Control node.\r
37 @retval FALSE It's not.\r
38\r
39**/\r
40BOOLEAN\r
41IsUartFlowControlNode (\r
42 IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl\r
43 )\r
44{\r
45 return (BOOLEAN) (\r
46 (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&\r
47 (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&\r
48 (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))\r
49 );\r
50}\r
51\r
6b008b74
RN
52/**\r
53 Check whether the device path node is ISA Serial Node.\r
54\r
55 @param Acpi Device path node to be checked\r
56\r
57 @retval TRUE It's ISA Serial Node.\r
58 @retval FALSE It's NOT ISA Serial Node.\r
59\r
60**/\r
61BOOLEAN\r
62IsIsaSerialNode (\r
63 IN ACPI_HID_DEVICE_PATH *Acpi\r
64 )\r
65{\r
66 return (BOOLEAN) (\r
67 (DevicePathType (Acpi) == ACPI_DEVICE_PATH) &&\r
68 (DevicePathSubType (Acpi) == ACPI_DP) &&\r
69 (ReadUnaligned32 (&Acpi->HID) == EISA_PNP_ID (0x0501))\r
70 );\r
71}\r
72\r
5c08e117 73/**\r
74 Update Com Ports attributes from DevicePath\r
75\r
76 @param DevicePath DevicePath that contains Com ports\r
77\r
78 @retval EFI_SUCCESS The update is successful.\r
79\r
80**/\r
81EFI_STATUS\r
82UpdateComAttributeFromVariable (\r
83 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
84 );\r
85\r
86/**\r
87 Update the multi-instance device path of Terminal Device based on\r
88 the global TerminalMenu. If ChangeTernimal is TRUE, the terminal \r
89 device path in the Terminal Device in TerminalMenu is also updated.\r
90\r
91 @param DevicePath The multi-instance device path.\r
92 @param ChangeTerminal TRUE, then device path in the Terminal Device \r
93 in TerminalMenu is also updated; FALSE, no update.\r
94\r
95 @return EFI_SUCCESS The function completes successfully.\r
96\r
97**/\r
98EFI_STATUS\r
99ChangeTerminalDevicePath (\r
8e491a81 100 IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
5c08e117 101 IN BOOLEAN ChangeTerminal\r
102 )\r
103{\r
104 EFI_DEVICE_PATH_PROTOCOL *Node;\r
105 EFI_DEVICE_PATH_PROTOCOL *Node1;\r
106 ACPI_HID_DEVICE_PATH *Acpi;\r
107 UART_DEVICE_PATH *Uart;\r
108 UART_DEVICE_PATH *Uart1;\r
109 UINTN Com;\r
5c08e117 110 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
111 BM_MENU_ENTRY *NewMenuEntry;\r
8e491a81 112 UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;\r
5c08e117 113\r
8e491a81 114 Node = *DevicePath;\r
5c08e117 115 Node = NextDevicePathNode (Node);\r
116 Com = 0;\r
117 while (!IsDevicePathEnd (Node)) {\r
6b008b74
RN
118 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
119 if (IsIsaSerialNode (Acpi)) {\r
120 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
5c08e117 121 }\r
122\r
123 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Com);\r
124\r
125 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
126 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
127 Uart = (UART_DEVICE_PATH *) Node;\r
128 CopyMem (\r
129 &Uart->BaudRate,\r
130 &NewTerminalContext->BaudRate,\r
131 sizeof (UINT64)\r
132 );\r
133\r
134 CopyMem (\r
135 &Uart->DataBits,\r
136 &NewTerminalContext->DataBits,\r
137 sizeof (UINT8)\r
138 );\r
139\r
140 CopyMem (\r
141 &Uart->Parity,\r
142 &NewTerminalContext->Parity,\r
143 sizeof (UINT8)\r
144 );\r
145\r
146 CopyMem (\r
147 &Uart->StopBits,\r
148 &NewTerminalContext->StopBits,\r
149 sizeof (UINT8)\r
150 );\r
8e491a81
ED
151\r
152 FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node);\r
153 if (IsUartFlowControlNode (FlowControlNode)) {\r
154 FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl;\r
155 } else {\r
156 //\r
157 // Append the Flow control device node when user enable flow control.\r
158 //\r
159 if (NewTerminalContext->FlowControl != 0) {\r
160 mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl;\r
161 *DevicePath = AppendDevicePathNode (\r
162 *DevicePath,\r
163 (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath)\r
164 );\r
165 }\r
166 }\r
167\r
5c08e117 168 //\r
169 // Change the device path in the ComPort\r
170 //\r
171 if (ChangeTerminal) {\r
172 Node1 = NewTerminalContext->DevicePath;\r
173 Node1 = NextDevicePathNode (Node1);\r
174 while (!IsDevicePathEnd (Node1)) {\r
175 if ((DevicePathType (Node1) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node1) == MSG_UART_DP)) {\r
176 Uart1 = (UART_DEVICE_PATH *) Node1;\r
177 CopyMem (\r
178 &Uart1->BaudRate,\r
179 &NewTerminalContext->BaudRate,\r
180 sizeof (UINT64)\r
181 );\r
182\r
183 CopyMem (\r
184 &Uart1->DataBits,\r
185 &NewTerminalContext->DataBits,\r
186 sizeof (UINT8)\r
187 );\r
188\r
189 CopyMem (\r
190 &Uart1->Parity,\r
191 &NewTerminalContext->Parity,\r
192 sizeof (UINT8)\r
193 );\r
194\r
195 CopyMem (\r
196 &Uart1->StopBits,\r
197 &NewTerminalContext->StopBits,\r
198 sizeof (UINT8)\r
199 );\r
200 break;\r
201 }\r
202 //\r
203 // end if\r
204 //\r
205 Node1 = NextDevicePathNode (Node1);\r
206 }\r
207 //\r
208 // end while\r
209 //\r
210 break;\r
211 }\r
212 }\r
213\r
214 Node = NextDevicePathNode (Node);\r
215 }\r
216\r
217 return EFI_SUCCESS;\r
218\r
219}\r
220\r
221/**\r
222 Update the device path that describing a terminal device\r
223 based on the new BaudRate, Data Bits, parity and Stop Bits\r
224 set.\r
225\r
226 @param DevicePath terminal device's path\r
227\r
228**/\r
229VOID\r
230ChangeVariableDevicePath (\r
231 IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
232 )\r
233{\r
234 EFI_DEVICE_PATH_PROTOCOL *Node;\r
235 ACPI_HID_DEVICE_PATH *Acpi;\r
236 UART_DEVICE_PATH *Uart;\r
237 UINTN Com;\r
5c08e117 238 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
239 BM_MENU_ENTRY *NewMenuEntry;\r
240\r
5c08e117 241 Node = DevicePath;\r
242 Node = NextDevicePathNode (Node);\r
243 Com = 0;\r
244 while (!IsDevicePathEnd (Node)) {\r
6b008b74
RN
245 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
246 if (IsIsaSerialNode (Acpi)) {\r
247 CopyMem (&Com, &Acpi->UID, sizeof (UINT32));\r
5c08e117 248 }\r
249\r
250 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
251 NewMenuEntry = BOpt_GetMenuEntry (\r
252 &TerminalMenu,\r
253 Com\r
254 );\r
255 ASSERT (NewMenuEntry != NULL);\r
256 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
257 Uart = (UART_DEVICE_PATH *) Node;\r
258 CopyMem (\r
259 &Uart->BaudRate,\r
260 &NewTerminalContext->BaudRate,\r
261 sizeof (UINT64)\r
262 );\r
263\r
264 CopyMem (\r
265 &Uart->DataBits,\r
266 &NewTerminalContext->DataBits,\r
267 sizeof (UINT8)\r
268 );\r
269\r
270 CopyMem (\r
271 &Uart->Parity,\r
272 &NewTerminalContext->Parity,\r
273 sizeof (UINT8)\r
274 );\r
275\r
276 CopyMem (\r
277 &Uart->StopBits,\r
278 &NewTerminalContext->StopBits,\r
279 sizeof (UINT8)\r
280 );\r
281 }\r
282\r
283 Node = NextDevicePathNode (Node);\r
284 }\r
285}\r
286\r
287/**\r
288 Retrieve ACPI UID of UART from device path\r
289\r
290 @param Handle The handle for the UART device.\r
291 @param AcpiUid The ACPI UID on output.\r
292\r
293 @retval TRUE Find valid UID from device path\r
294 @retval FALSE Can't find\r
295\r
296**/\r
297BOOLEAN\r
298RetrieveUartUid (\r
299 IN EFI_HANDLE Handle,\r
300 IN OUT UINT32 *AcpiUid\r
301 )\r
302{\r
6b008b74 303 EFI_STATUS Status;\r
5c08e117 304 ACPI_HID_DEVICE_PATH *Acpi;\r
305 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
306\r
6b008b74
RN
307 Status = gBS->HandleProtocol (\r
308 Handle,\r
309 &gEfiDevicePathProtocolGuid,\r
310 (VOID **) &DevicePath\r
311 );\r
312 if (EFI_ERROR (Status)) {\r
313 return FALSE;\r
5c08e117 314 }\r
315\r
6b008b74
RN
316 Acpi = NULL;\r
317 for (; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {\r
318 if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (DevicePath) == MSG_UART_DP)) {\r
319 break;\r
320 }\r
321 //\r
322 // Acpi points to the node before the Uart node\r
323 //\r
324 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;\r
325 }\r
5c08e117 326\r
6b008b74 327 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
5c08e117 328 if (AcpiUid != NULL) {\r
6b008b74 329 CopyMem (AcpiUid, &Acpi->UID, sizeof (UINT32));\r
5c08e117 330 }\r
331 return TRUE;\r
332 } else {\r
333 return FALSE;\r
334 }\r
335}\r
336\r
337/**\r
338 Sort Uart handles array with Acpi->UID from low to high.\r
339\r
340 @param Handles EFI_SERIAL_IO_PROTOCOL handle buffer\r
341 @param NoHandles EFI_SERIAL_IO_PROTOCOL handle count\r
342**/\r
343VOID\r
344SortedUartHandle (\r
345 IN EFI_HANDLE *Handles,\r
346 IN UINTN NoHandles\r
347 )\r
348{\r
349 UINTN Index1;\r
350 UINTN Index2;\r
351 UINTN Position;\r
352 UINT32 AcpiUid1;\r
353 UINT32 AcpiUid2;\r
354 UINT32 TempAcpiUid;\r
355 EFI_HANDLE TempHandle;\r
356\r
357 for (Index1 = 0; Index1 < NoHandles-1; Index1++) {\r
358 if (!RetrieveUartUid (Handles[Index1], &AcpiUid1)) {\r
359 continue;\r
360 }\r
361 TempHandle = Handles[Index1];\r
362 Position = Index1;\r
363 TempAcpiUid = AcpiUid1;\r
364\r
365 for (Index2 = Index1+1; Index2 < NoHandles; Index2++) {\r
366 if (!RetrieveUartUid (Handles[Index2], &AcpiUid2)) {\r
367 continue;\r
368 }\r
369 if (AcpiUid2 < TempAcpiUid) {\r
370 TempAcpiUid = AcpiUid2;\r
371 TempHandle = Handles[Index2];\r
372 Position = Index2;\r
373 }\r
374 }\r
375 Handles[Position] = Handles[Index1];\r
376 Handles[Index1] = TempHandle;\r
377 }\r
378}\r
379\r
380/**\r
381 Test whether DevicePath is a valid Terminal\r
382\r
383\r
384 @param DevicePath DevicePath to be checked\r
385 @param Termi If DevicePath is valid Terminal, terminal type is returned.\r
386 @param Com If DevicePath is valid Terminal, Com Port type is returned.\r
387\r
388 @retval TRUE If DevicePath point to a Terminal.\r
389 @retval FALSE If DevicePath does not point to a Terminal.\r
390\r
391**/\r
392BOOLEAN\r
393IsTerminalDevicePath (\r
394 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
395 OUT TYPE_OF_TERMINAL *Termi,\r
396 OUT UINTN *Com\r
397 );\r
398\r
399/**\r
400 Build a list containing all serial devices.\r
401\r
402\r
403 @retval EFI_SUCCESS The function complete successfully.\r
404 @retval EFI_UNSUPPORTED No serial ports present.\r
405\r
406**/\r
407EFI_STATUS\r
408LocateSerialIo (\r
409 VOID\r
410 )\r
411{\r
5c08e117 412 UINTN Index;\r
413 UINTN Index2;\r
414 UINTN NoHandles;\r
415 EFI_HANDLE *Handles;\r
416 EFI_STATUS Status;\r
417 ACPI_HID_DEVICE_PATH *Acpi;\r
418 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
5c08e117 419 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
6b008b74 420 EFI_DEVICE_PATH_PROTOCOL *Node;\r
5c08e117 421 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;\r
422 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;\r
423 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;\r
424 BM_MENU_ENTRY *NewMenuEntry;\r
425 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
426 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
427 VENDOR_DEVICE_PATH Vendor;\r
8e491a81 428 UINT32 FlowControl;\r
5c08e117 429 //\r
430 // Get all handles that have SerialIo protocol installed\r
431 //\r
432 InitializeListHead (&TerminalMenu.Head);\r
433 TerminalMenu.MenuNumber = 0;\r
434 Status = gBS->LocateHandleBuffer (\r
435 ByProtocol,\r
436 &gEfiSerialIoProtocolGuid,\r
437 NULL,\r
438 &NoHandles,\r
439 &Handles\r
440 );\r
441 if (EFI_ERROR (Status)) {\r
442 //\r
443 // No serial ports present\r
444 //\r
445 return EFI_UNSUPPORTED;\r
446 }\r
447\r
448 //\r
449 // Sort Uart handles array with Acpi->UID from low to high\r
450 // then Terminal menu can be built from low Acpi->UID to high Acpi->UID\r
451 //\r
452 SortedUartHandle (Handles, NoHandles);\r
453\r
454 for (Index = 0; Index < NoHandles; Index++) {\r
455 //\r
456 // Check to see whether the handle has DevicePath Protocol installed\r
457 //\r
458 gBS->HandleProtocol (\r
459 Handles[Index],\r
460 &gEfiDevicePathProtocolGuid,\r
461 (VOID **) &DevicePath\r
462 );\r
5c08e117 463\r
6b008b74
RN
464 Acpi = NULL;\r
465 for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
466 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
467 break;\r
468 }\r
469 //\r
470 // Acpi points to the node before Uart node\r
471 //\r
472 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
473 }\r
5c08e117 474\r
6b008b74 475 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
5c08e117 476 NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);\r
477 if (NewMenuEntry == NULL) {\r
478 FreePool (Handles);\r
479 return EFI_OUT_OF_RESOURCES;\r
480 }\r
481\r
482 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
483 CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));\r
484 NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);\r
485 //\r
486 // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!\r
487 // coz' the misc data for each platform is not correct, actually it's the device path stored in\r
488 // datahub which is not completed, so a searching for end of device path will enter a\r
489 // dead-loop.\r
490 //\r
491 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);\r
492 if (NULL == NewMenuEntry->DisplayString) {\r
493 NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);\r
494 }\r
495\r
496 NewMenuEntry->HelpString = NULL;\r
497\r
498 gBS->HandleProtocol (\r
499 Handles[Index],\r
500 &gEfiSerialIoProtocolGuid,\r
501 (VOID **) &SerialIo\r
502 );\r
503\r
504 CopyMem (\r
505 &NewTerminalContext->BaudRate,\r
506 &SerialIo->Mode->BaudRate,\r
507 sizeof (UINT64)\r
508 );\r
509\r
510 CopyMem (\r
511 &NewTerminalContext->DataBits,\r
512 &SerialIo->Mode->DataBits,\r
513 sizeof (UINT8)\r
514 );\r
515\r
516 CopyMem (\r
517 &NewTerminalContext->Parity,\r
518 &SerialIo->Mode->Parity,\r
519 sizeof (UINT8)\r
520 );\r
521\r
522 CopyMem (\r
523 &NewTerminalContext->StopBits,\r
524 &SerialIo->Mode->StopBits,\r
525 sizeof (UINT8)\r
526 );\r
8e491a81
ED
527\r
528 NewTerminalContext->FlowControl = 0;\r
529 SerialIo->GetControl(SerialIo, &FlowControl);\r
530 if ((FlowControl & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) != 0) {\r
531 NewTerminalContext->FlowControl = UART_FLOW_CONTROL_HARDWARE;\r
532 }\r
533\r
5c08e117 534 InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);\r
535 TerminalMenu.MenuNumber++;\r
536 }\r
537 }\r
538 if (Handles != NULL) {\r
539 FreePool (Handles);\r
540 }\r
541\r
542 //\r
543 // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var\r
544 //\r
545 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);\r
546 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);\r
547 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);\r
548 if (OutDevicePath != NULL) {\r
549 UpdateComAttributeFromVariable (OutDevicePath);\r
550 }\r
551\r
552 if (InpDevicePath != NULL) {\r
553 UpdateComAttributeFromVariable (InpDevicePath);\r
554 }\r
555\r
556 if (ErrDevicePath != NULL) {\r
557 UpdateComAttributeFromVariable (ErrDevicePath);\r
558 }\r
559\r
560 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
561 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\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\r
568 NewTerminalContext->TerminalType = 0;\r
569 NewTerminalContext->IsConIn = FALSE;\r
570 NewTerminalContext->IsConOut = FALSE;\r
571 NewTerminalContext->IsStdErr = FALSE;\r
572\r
573 Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
574 Vendor.Header.SubType = MSG_VENDOR_DP;\r
575\r
576 for (Index2 = 0; Index2 < 4; Index2++) {\r
577 CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));\r
578 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
579 NewDevicePath = AppendDevicePathNode (\r
580 NewTerminalContext->DevicePath,\r
581 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor\r
582 );\r
583 if (NewMenuEntry->HelpString != NULL) {\r
584 FreePool (NewMenuEntry->HelpString);\r
585 }\r
586 //\r
587 // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);\r
588 // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;\r
589 //\r
590 NewMenuEntry->HelpString = NULL;\r
591\r
592 if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {\r
593 NewTerminalContext->IsConOut = TRUE;\r
594 NewTerminalContext->TerminalType = (UINT8) Index2;\r
595 }\r
596\r
597 if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {\r
598 NewTerminalContext->IsConIn = TRUE;\r
599 NewTerminalContext->TerminalType = (UINT8) Index2;\r
600 }\r
601\r
602 if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {\r
603 NewTerminalContext->IsStdErr = TRUE;\r
604 NewTerminalContext->TerminalType = (UINT8) Index2;\r
605 }\r
606 }\r
607 }\r
608\r
609 return EFI_SUCCESS;\r
610}\r
611\r
612/**\r
613 Update Com Ports attributes from DevicePath\r
614\r
615 @param DevicePath DevicePath that contains Com ports\r
616\r
617 @retval EFI_SUCCESS The update is successful.\r
618 @retval EFI_NOT_FOUND Can not find specific menu entry\r
619**/\r
620EFI_STATUS\r
621UpdateComAttributeFromVariable (\r
622 EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
623 )\r
624{\r
625 EFI_DEVICE_PATH_PROTOCOL *Node;\r
626 EFI_DEVICE_PATH_PROTOCOL *SerialNode;\r
627 ACPI_HID_DEVICE_PATH *Acpi;\r
628 UART_DEVICE_PATH *Uart;\r
629 UART_DEVICE_PATH *Uart1;\r
5c08e117 630 UINTN TerminalNumber;\r
631 BM_MENU_ENTRY *NewMenuEntry;\r
632 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
633 UINTN Index;\r
8e491a81
ED
634 UART_FLOW_CONTROL_DEVICE_PATH *FlowControlNode;\r
635 BOOLEAN HasFlowControlNode;\r
5c08e117 636\r
8e491a81 637 HasFlowControlNode = FALSE;\r
5c08e117 638 Node = DevicePath;\r
639 Node = NextDevicePathNode (Node);\r
640 TerminalNumber = 0;\r
641 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
642 while (!IsDevicePathEnd (Node)) {\r
6b008b74
RN
643 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
644 if (IsIsaSerialNode (Acpi)) {\r
645 CopyMem (&TerminalNumber, &Acpi->UID, sizeof (UINT32));\r
5c08e117 646 }\r
647\r
648 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
649 Uart = (UART_DEVICE_PATH *) Node;\r
650 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalNumber);\r
651 if (NULL == NewMenuEntry) {\r
652 return EFI_NOT_FOUND;\r
653 }\r
654\r
655 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
656 CopyMem (\r
657 &NewTerminalContext->BaudRate,\r
658 &Uart->BaudRate,\r
659 sizeof (UINT64)\r
660 );\r
661\r
662 CopyMem (\r
663 &NewTerminalContext->DataBits,\r
664 &Uart->DataBits,\r
665 sizeof (UINT8)\r
666 );\r
667\r
668 CopyMem (\r
669 &NewTerminalContext->Parity,\r
670 &Uart->Parity,\r
671 sizeof (UINT8)\r
672 );\r
673\r
674 CopyMem (\r
675 &NewTerminalContext->StopBits,\r
676 &Uart->StopBits,\r
677 sizeof (UINT8)\r
678 );\r
679\r
8e491a81
ED
680 FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Node);\r
681 if (IsUartFlowControlNode (FlowControlNode)) {\r
682 HasFlowControlNode = TRUE;\r
683 NewTerminalContext->FlowControl = (UINT8) ReadUnaligned32 (&FlowControlNode->FlowControlMap);\r
684 } else if (NewTerminalContext->FlowControl != 0) {\r
685 //\r
686 // No Flow Control device path node, assumption no Flow control\r
687 //\r
688 NewTerminalContext->FlowControl = 0;\r
689 }\r
690\r
5c08e117 691 SerialNode = NewTerminalContext->DevicePath;\r
692 SerialNode = NextDevicePathNode (SerialNode);\r
693 while (!IsDevicePathEnd (SerialNode)) {\r
694 if ((DevicePathType (SerialNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (SerialNode) == MSG_UART_DP)) {\r
695 //\r
696 // Update following device paths according to\r
697 // previous acquired uart attributes\r
698 //\r
699 Uart1 = (UART_DEVICE_PATH *) SerialNode;\r
700 CopyMem (\r
701 &Uart1->BaudRate,\r
702 &NewTerminalContext->BaudRate,\r
703 sizeof (UINT64)\r
704 );\r
705\r
706 CopyMem (\r
707 &Uart1->DataBits,\r
708 &NewTerminalContext->DataBits,\r
709 sizeof (UINT8)\r
710 );\r
711 CopyMem (\r
712 &Uart1->Parity,\r
713 &NewTerminalContext->Parity,\r
714 sizeof (UINT8)\r
715 );\r
716 CopyMem (\r
717 &Uart1->StopBits,\r
718 &NewTerminalContext->StopBits,\r
719 sizeof (UINT8)\r
720 );\r
721\r
8e491a81
ED
722 FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (SerialNode);\r
723 if (IsUartFlowControlNode (FlowControlNode)) {\r
724 FlowControlNode->FlowControlMap = NewTerminalContext->FlowControl;\r
725 } else {\r
726 if (HasFlowControlNode) {\r
727 mFlowControlDevicePath.FlowControlMap = NewTerminalContext->FlowControl;\r
728 NewTerminalContext->DevicePath = AppendDevicePathNode (\r
729 NewTerminalContext->DevicePath,\r
730 (EFI_DEVICE_PATH_PROTOCOL *) (&mFlowControlDevicePath)\r
731 );\r
732 }\r
733 }\r
5c08e117 734 break;\r
735 }\r
736\r
737 SerialNode = NextDevicePathNode (SerialNode);\r
738 }\r
739 //\r
740 // end while\r
741 //\r
742 }\r
743\r
744 Node = NextDevicePathNode (Node);\r
745 }\r
746 //\r
747 // end while\r
748 //\r
749 }\r
750\r
751 return EFI_SUCCESS;\r
752}\r
753\r
754/**\r
755 Build up Console Menu based on types passed in. The type can\r
756 be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT\r
757 and BM_CONSOLE_ERR_CONTEXT_SELECT.\r
758\r
759 @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT\r
760 and BM_CONSOLE_ERR_CONTEXT_SELECT.\r
761\r
762 @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.\r
763 @retval EFI_NOT_FOUND If the EFI Variable defined in UEFI spec with name "ConOutDev", \r
764 "ConInDev" or "ConErrDev" doesn't exists.\r
765 @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.\r
766 @retval EFI_SUCCESS Function completes successfully.\r
767\r
768**/\r
769EFI_STATUS\r
770GetConsoleMenu (\r
771 IN UINTN ConsoleMenuType\r
772 )\r
773{\r
774 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
775 EFI_DEVICE_PATH_PROTOCOL *AllDevicePath;\r
776 EFI_DEVICE_PATH_PROTOCOL *MultiDevicePath;\r
777 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;\r
778 UINTN Size;\r
779 UINTN AllCount;\r
780 UINTN Index;\r
781 UINTN Index2;\r
782 BM_MENU_ENTRY *NewMenuEntry;\r
783 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
784 TYPE_OF_TERMINAL Terminal;\r
785 UINTN Com;\r
786 BM_MENU_OPTION *ConsoleMenu;\r
787\r
788 DevicePath = NULL;\r
789 AllDevicePath = NULL;\r
790 AllCount = 0;\r
791 switch (ConsoleMenuType) {\r
792 case BM_CONSOLE_IN_CONTEXT_SELECT:\r
793 ConsoleMenu = &ConsoleInpMenu;\r
794 DevicePath = EfiLibGetVariable (\r
795 L"ConIn",\r
796 &gEfiGlobalVariableGuid\r
797 );\r
798\r
799 AllDevicePath = EfiLibGetVariable (\r
800 L"ConInDev",\r
801 &gEfiGlobalVariableGuid\r
802 );\r
803 break;\r
804\r
805 case BM_CONSOLE_OUT_CONTEXT_SELECT:\r
806 ConsoleMenu = &ConsoleOutMenu;\r
807 DevicePath = EfiLibGetVariable (\r
808 L"ConOut",\r
809 &gEfiGlobalVariableGuid\r
810 );\r
811\r
812 AllDevicePath = EfiLibGetVariable (\r
813 L"ConOutDev",\r
814 &gEfiGlobalVariableGuid\r
815 );\r
816 break;\r
817\r
818 case BM_CONSOLE_ERR_CONTEXT_SELECT:\r
819 ConsoleMenu = &ConsoleErrMenu;\r
820 DevicePath = EfiLibGetVariable (\r
821 L"ErrOut",\r
822 &gEfiGlobalVariableGuid\r
823 );\r
824\r
825 AllDevicePath = EfiLibGetVariable (\r
826 L"ErrOutDev",\r
827 &gEfiGlobalVariableGuid\r
828 );\r
829 break;\r
830\r
831 default:\r
832 return EFI_UNSUPPORTED;\r
833 }\r
834\r
835 if (NULL == AllDevicePath) {\r
836 return EFI_NOT_FOUND;\r
837 }\r
838\r
839 InitializeListHead (&ConsoleMenu->Head);\r
840\r
841 AllCount = EfiDevicePathInstanceCount (AllDevicePath);\r
842 ConsoleMenu->MenuNumber = 0;\r
843 //\r
844 // Following is menu building up for Console Devices selected.\r
845 //\r
846 MultiDevicePath = AllDevicePath;\r
847 Index2 = 0;\r
848 for (Index = 0; Index < AllCount; Index++) {\r
849 DevicePathInst = GetNextDevicePathInstance (&MultiDevicePath, &Size);\r
850\r
851 NewMenuEntry = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);\r
852 if (NULL == NewMenuEntry) {\r
853 return EFI_OUT_OF_RESOURCES;\r
854 }\r
855\r
856 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
857 NewMenuEntry->OptionNumber = Index2;\r
858\r
859 NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);\r
84fa6c17 860 ASSERT (NewConsoleContext->DevicePath != NULL);\r
5c08e117 861 NewMenuEntry->DisplayString = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);\r
862 if (NULL == NewMenuEntry->DisplayString) {\r
863 NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);\r
864 }\r
865\r
866 NewConsoleContext->IsTerminal = IsTerminalDevicePath (\r
867 NewConsoleContext->DevicePath,\r
868 &Terminal,\r
869 &Com\r
870 );\r
871\r
872 NewConsoleContext->IsActive = BdsLibMatchDevicePaths (\r
873 DevicePath,\r
874 NewConsoleContext->DevicePath\r
875 );\r
876\r
877 if (NewConsoleContext->IsTerminal) {\r
878 BOpt_DestroyMenuEntry (NewMenuEntry);\r
879 } else {\r
880 Index2++;\r
881 ConsoleMenu->MenuNumber++;\r
882 InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);\r
883 }\r
884 }\r
885\r
886 return EFI_SUCCESS;\r
887}\r
888\r
889/**\r
890 Build up ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
891\r
892 @retval EFI_SUCCESS The function always complete successfully.\r
893\r
894**/\r
895EFI_STATUS\r
896GetAllConsoles (\r
897 VOID\r
898 )\r
899{\r
900 GetConsoleMenu (BM_CONSOLE_IN_CONTEXT_SELECT);\r
901 GetConsoleMenu (BM_CONSOLE_OUT_CONTEXT_SELECT);\r
902 GetConsoleMenu (BM_CONSOLE_ERR_CONTEXT_SELECT);\r
903 return EFI_SUCCESS;\r
904}\r
905\r
906/**\r
907 Free ConsoleOutMenu, ConsoleInpMenu and ConsoleErrMenu\r
908\r
909 @retval EFI_SUCCESS The function always complete successfully.\r
910**/\r
911EFI_STATUS\r
912FreeAllConsoles (\r
913 VOID\r
914 )\r
915{\r
916 BOpt_FreeMenu (&ConsoleOutMenu);\r
917 BOpt_FreeMenu (&ConsoleInpMenu);\r
918 BOpt_FreeMenu (&ConsoleErrMenu);\r
919 BOpt_FreeMenu (&TerminalMenu);\r
920 return EFI_SUCCESS;\r
921}\r
922\r
923/**\r
924 Test whether DevicePath is a valid Terminal\r
925\r
926\r
927 @param DevicePath DevicePath to be checked\r
928 @param Termi If DevicePath is valid Terminal, terminal type is returned.\r
929 @param Com If DevicePath is valid Terminal, Com Port type is returned.\r
930\r
931 @retval TRUE If DevicePath point to a Terminal.\r
932 @retval FALSE If DevicePath does not point to a Terminal.\r
933\r
934**/\r
935BOOLEAN\r
936IsTerminalDevicePath (\r
937 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
938 OUT TYPE_OF_TERMINAL *Termi,\r
939 OUT UINTN *Com\r
940 )\r
941{\r
6b008b74
RN
942 BOOLEAN IsTerminal;\r
943 EFI_DEVICE_PATH_PROTOCOL *Node;\r
944 VENDOR_DEVICE_PATH *Vendor;\r
945 UART_DEVICE_PATH *Uart;\r
946 ACPI_HID_DEVICE_PATH *Acpi;\r
5c08e117 947\r
948 IsTerminal = FALSE;\r
949\r
6b008b74
RN
950 Uart = NULL;\r
951 Vendor = NULL;\r
952 Acpi = NULL;\r
953 for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
954 //\r
955 // Vendor points to the node before the End node\r
956 //\r
957 Vendor = (VENDOR_DEVICE_PATH *) Node;\r
958\r
959 if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {\r
960 Uart = (UART_DEVICE_PATH *) Node;\r
961 }\r
962\r
963 if (Uart == NULL) {\r
964 //\r
965 // Acpi points to the node before the UART node\r
966 //\r
967 Acpi = (ACPI_HID_DEVICE_PATH *) Node;\r
968 }\r
5c08e117 969 }\r
970\r
6b008b74
RN
971 if (Vendor == NULL ||\r
972 DevicePathType (Vendor) != MESSAGING_DEVICE_PATH ||\r
973 DevicePathSubType (Vendor) != MSG_VENDOR_DP ||\r
974 Uart == NULL) {\r
975 return FALSE;\r
976 }\r
5c08e117 977\r
978 //\r
979 // There are four kinds of Terminal types\r
980 // check to see whether this devicepath\r
981 // is one of that type\r
982 //\r
6b008b74 983 if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[0])) {\r
13078b3f 984 *Termi = TerminalTypePcAnsi;\r
5c08e117 985 IsTerminal = TRUE;\r
986 } else {\r
6b008b74 987 if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[1])) {\r
13078b3f 988 *Termi = TerminalTypeVt100;\r
5c08e117 989 IsTerminal = TRUE;\r
990 } else {\r
6b008b74 991 if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[2])) {\r
13078b3f 992 *Termi = TerminalTypeVt100Plus;\r
5c08e117 993 IsTerminal = TRUE;\r
994 } else {\r
6b008b74 995 if (CompareGuid (&Vendor->Guid, &TerminalTypeGuid[3])) {\r
13078b3f 996 *Termi = TerminalTypeVtUtf8;\r
5c08e117 997 IsTerminal = TRUE;\r
998 } else {\r
999 IsTerminal = FALSE;\r
1000 }\r
1001 }\r
1002 }\r
1003 }\r
1004\r
1005 if (!IsTerminal) {\r
1006 return FALSE;\r
1007 }\r
1008\r
6b008b74 1009 if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {\r
5c08e117 1010 CopyMem (Com, &Acpi->UID, sizeof (UINT32));\r
1011 } else {\r
1012 return FALSE;\r
1013 }\r
1014\r
1015 return TRUE;\r
1016}\r
1017\r
1018/**\r
1019 Get mode number according to column and row\r
1020\r
1021 @param CallbackData The BMM context data.\r
1022**/\r
1023VOID\r
1024GetConsoleOutMode (\r
1025 IN BMM_CALLBACK_DATA *CallbackData\r
1026 )\r
1027{\r
1028 UINTN Col;\r
1029 UINTN Row;\r
1030 UINTN CurrentCol;\r
1031 UINTN CurrentRow;\r
1032 UINTN Mode;\r
1033 UINTN MaxMode;\r
1034 EFI_STATUS Status;\r
5c08e117 1035 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;\r
1036\r
1037 ConOut = gST->ConOut;\r
1038 MaxMode = (UINTN) (ConOut->Mode->MaxMode);\r
6aa22a17 1039\r
32bc1227 1040 CurrentCol = PcdGet32 (PcdSetupConOutColumn);\r
1041 CurrentRow = PcdGet32 (PcdSetupConOutRow);\r
6aa22a17 1042 for (Mode = 0; Mode < MaxMode; Mode++) {\r
1043 Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);\r
1044 if (!EFI_ERROR(Status)) {\r
1045 if (CurrentCol == Col && CurrentRow == Row) {\r
1046 CallbackData->BmmFakeNvData.ConsoleOutMode = (UINT16) Mode;\r
1047 break;\r
5c08e117 1048 }\r
1049 }\r
5c08e117 1050 }\r
1051}\r
be9304f3
ED
1052\r
1053/**\r
1054\r
1055 Initialize console input device check box to ConsoleInCheck[MAX_MENU_NUMBER]\r
1056 in BMM_FAKE_NV_DATA structure.\r
1057\r
1058 @param CallbackData The BMM context data.\r
1059\r
1060**/ \r
1061VOID \r
1062GetConsoleInCheck (\r
1063 IN BMM_CALLBACK_DATA *CallbackData\r
1064 )\r
1065{\r
1066 UINT16 Index;\r
1067 BM_MENU_ENTRY *NewMenuEntry; \r
1068 UINT8 *ConInCheck;\r
1069 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
1070 \r
1071 ASSERT (CallbackData != NULL);\r
1072 \r
1073 ConInCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];\r
1074 for (Index = 0; ((Index < ConsoleInpMenu.MenuNumber) && \\r
1075 (Index < MAX_MENU_NUMBER)) ; Index++) { \r
1076 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
1077 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; \r
1078 ConInCheck[Index] = NewConsoleContext->IsActive;\r
1079 }\r
1080}\r
1081\r
1082/**\r
1083\r
1084 Initialize console output device check box to ConsoleOutCheck[MAX_MENU_NUMBER]\r
1085 in BMM_FAKE_NV_DATA structure.\r
1086\r
1087 @param CallbackData The BMM context data.\r
1088\r
1089**/ \r
1090VOID \r
1091GetConsoleOutCheck (\r
1092 IN BMM_CALLBACK_DATA *CallbackData\r
1093 )\r
1094{\r
1095 UINT16 Index;\r
1096 BM_MENU_ENTRY *NewMenuEntry; \r
1097 UINT8 *ConOutCheck;\r
1098 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
1099 \r
1100 ASSERT (CallbackData != NULL);\r
1101 ConOutCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];\r
1102 for (Index = 0; ((Index < ConsoleOutMenu.MenuNumber) && \\r
1103 (Index < MAX_MENU_NUMBER)) ; Index++) { \r
1104 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
1105 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; \r
1106 ConOutCheck[Index] = NewConsoleContext->IsActive;\r
1107 }\r
1108}\r
1109 \r
1110/**\r
1111\r
1112 Initialize standard error output device check box to ConsoleErrCheck[MAX_MENU_NUMBER]\r
1113 in BMM_FAKE_NV_DATA structure.\r
1114\r
1115 @param CallbackData The BMM context data.\r
1116\r
1117**/ \r
1118VOID \r
1119GetConsoleErrCheck (\r
1120 IN BMM_CALLBACK_DATA *CallbackData\r
1121 )\r
1122{\r
1123 UINT16 Index;\r
1124 BM_MENU_ENTRY *NewMenuEntry; \r
1125 UINT8 *ConErrCheck;\r
1126 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
1127 \r
1128 ASSERT (CallbackData != NULL);\r
1129 ConErrCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];\r
1130 for (Index = 0; ((Index < ConsoleErrMenu.MenuNumber) && \\r
1131 (Index < MAX_MENU_NUMBER)) ; Index++) { \r
1132 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
1133 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext; \r
1134 ConErrCheck[Index] = NewConsoleContext->IsActive;\r
1135 }\r
1136}\r
1137\r
1138/**\r
1139\r
1140 Initialize terminal attributes (baudrate, data rate, stop bits, parity and terminal type)\r
1141 to BMM_FAKE_NV_DATA structure.\r
1142\r
1143 @param CallbackData The BMM context data.\r
1144\r
1145**/ \r
1146VOID \r
1147GetTerminalAttribute (\r
1148 IN BMM_CALLBACK_DATA *CallbackData\r
1149 )\r
1150{\r
1151 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
1152 BM_MENU_ENTRY *NewMenuEntry;\r
1153 BM_TERMINAL_CONTEXT *NewTerminalContext; \r
1154 UINT16 TerminalIndex; \r
1155 UINT8 AttributeIndex;\r
1156\r
1157 ASSERT (CallbackData != NULL);\r
1158 \r
1159 CurrentFakeNVMap = &CallbackData->BmmFakeNvData; \r
1160 for (TerminalIndex = 0; ((TerminalIndex < TerminalMenu.MenuNumber) && \\r
1161 (TerminalIndex < MAX_MENU_NUMBER)); TerminalIndex++) { \r
1162 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, TerminalIndex);\r
1163 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
1164 for (AttributeIndex = 0; AttributeIndex < sizeof (BaudRateList) / sizeof (BaudRateList [0]); AttributeIndex++) {\r
1165 if (NewTerminalContext->BaudRate == (UINT64) (BaudRateList[AttributeIndex].Value)) {\r
1166 NewTerminalContext->BaudRateIndex = AttributeIndex;\r
1167 break;\r
1168 }\r
1169 }\r
bdb898a5 1170 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (DataBitsList); AttributeIndex++) {\r
be9304f3
ED
1171 if (NewTerminalContext->DataBits == (UINT64) (DataBitsList[AttributeIndex].Value)) {\r
1172 NewTerminalContext->DataBitsIndex = AttributeIndex;\r
1173 break;\r
1174 }\r
1175 } \r
1176 \r
bdb898a5 1177 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (ParityList); AttributeIndex++) {\r
be9304f3
ED
1178 if (NewTerminalContext->Parity == (UINT64) (ParityList[AttributeIndex].Value)) {\r
1179 NewTerminalContext->ParityIndex = AttributeIndex;\r
1180 break;\r
1181 }\r
1182 } \r
1183 \r
bdb898a5 1184 for (AttributeIndex = 0; AttributeIndex < ARRAY_SIZE (StopBitsList); AttributeIndex++) {\r
be9304f3
ED
1185 if (NewTerminalContext->StopBits == (UINT64) (StopBitsList[AttributeIndex].Value)) {\r
1186 NewTerminalContext->StopBitsIndex = AttributeIndex;\r
1187 break;\r
1188 }\r
1189 } \r
1190 CurrentFakeNVMap->COMBaudRate[TerminalIndex] = NewTerminalContext->BaudRateIndex;\r
1191 CurrentFakeNVMap->COMDataRate[TerminalIndex] = NewTerminalContext->DataBitsIndex;\r
1192 CurrentFakeNVMap->COMStopBits[TerminalIndex] = NewTerminalContext->StopBitsIndex;\r
1193 CurrentFakeNVMap->COMParity[TerminalIndex] = NewTerminalContext->ParityIndex; \r
1194 CurrentFakeNVMap->COMTerminalType[TerminalIndex] = NewTerminalContext->TerminalType;\r
1195 CurrentFakeNVMap->COMFlowControl[TerminalIndex] = NewTerminalContext->FlowControl;\r
1196 } \r
1197}\r
1198\r