]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c
provide a temporary method to generate SecMain executable file.
[mirror_edk2.git] / MdeModulePkg / Universal / Console / TerminalDxe / Terminal.c
CommitLineData
fb0b259e 1/** @file\r
2 Produces Simple Text Input Protocl, Simple Text Input Extended Protocol and\r
3 Simple Text Output Protocol upon Serial IO Protocol.\r
95276127 4\r
fb0b259e 5Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
95276127 6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
fb0b259e 14**/\r
95276127 15\r
16\r
95276127 17#include "Terminal.h"\r
18\r
66aa04e4 19STATIC\r
20EFI_STATUS\r
21TerminalFreeNotifyList (\r
22 IN OUT LIST_ENTRY *ListHead\r
fb0b259e 23 );\r
66aa04e4 24\r
95276127 25//\r
26// Globals\r
27//\r
28EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding = {\r
29 TerminalDriverBindingSupported,\r
30 TerminalDriverBindingStart,\r
31 TerminalDriverBindingStop,\r
32 0xa,\r
33 NULL,\r
34 NULL\r
35};\r
36\r
37\r
6b88ceec
A
38EFI_GUID *gTerminalType[] = {\r
39 &gEfiPcAnsiGuid,\r
40 &gEfiVT100Guid,\r
41 &gEfiVT100PlusGuid,\r
42 &gEfiVTUTF8Guid\r
43};\r
44\r
45\r
46TERMINAL_DEV gTerminalDevTemplate = {\r
47 TERMINAL_DEV_SIGNATURE,\r
48 NULL,\r
49 0,\r
50 NULL,\r
51 NULL,\r
52 { // SimpleTextInput\r
53 TerminalConInReset,\r
54 TerminalConInReadKeyStroke,\r
55 NULL\r
56 },\r
57 { // SimpleTextOutput\r
58 TerminalConOutReset,\r
59 TerminalConOutOutputString,\r
60 TerminalConOutTestString,\r
61 TerminalConOutQueryMode,\r
62 TerminalConOutSetMode,\r
63 TerminalConOutSetAttribute,\r
64 TerminalConOutClearScreen,\r
65 TerminalConOutSetCursorPosition,\r
66 TerminalConOutEnableCursor,\r
67 NULL\r
68 },\r
69 { // SimpleTextOutputMode\r
70 1, // MaxMode\r
71 0, // Mode?\r
72 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK), // Attribute\r
73 0, // CursorColumn\r
74 0, // CursorRow\r
75 TRUE // CursorVisible\r
76 },\r
77 0,\r
78 {\r
79 0,\r
80 0,\r
81 { 0 }\r
82 },\r
83 {\r
84 0,\r
85 0,\r
86 { 0 }\r
87 },\r
88 {\r
89 0,\r
90 0,\r
84b5c78e 91 { {0} }\r
6b88ceec
A
92 },\r
93 NULL, // ControllerNameTable\r
fb0b259e 94 NULL,\r
6b88ceec
A
95 INPUT_STATE_DEFAULT,\r
96 RESET_STATE_DEFAULT,\r
66aa04e4 97 FALSE,\r
98 { // SimpleTextInputEx\r
99 TerminalConInResetEx,\r
100 TerminalConInReadKeyStrokeEx,\r
101 NULL,\r
102 TerminalConInSetState,\r
103 TerminalConInRegisterKeyNotify,\r
104 TerminalConInUnregisterKeyNotify,\r
105 },\r
106 {\r
107 NULL,\r
108 NULL,\r
109 }\r
6b88ceec
A
110};\r
111\r
112\r
113\r
95276127 114EFI_STATUS\r
115EFIAPI\r
116TerminalDriverBindingSupported (\r
117 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
118 IN EFI_HANDLE Controller,\r
119 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
120 )\r
121{\r
122 EFI_STATUS Status;\r
123 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
124 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
125 VENDOR_DEVICE_PATH *Node;\r
126\r
127 //\r
128 // If remaining device path is not NULL, then make sure it is a\r
129 // device path that describes a terminal communications protocol.\r
130 //\r
131 if (RemainingDevicePath != NULL) {\r
132\r
133 Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;\r
134\r
135 if (Node->Header.Type != MESSAGING_DEVICE_PATH ||\r
136 Node->Header.SubType != MSG_VENDOR_DP ||\r
137 DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {\r
138\r
139 return EFI_UNSUPPORTED;\r
140\r
141 }\r
142 //\r
143 // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types\r
144 //\r
145 if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&\r
146 !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&\r
147 !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&\r
148 !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
149\r
150 return EFI_UNSUPPORTED;\r
151 }\r
152 }\r
153 //\r
154 // Open the IO Abstraction(s) needed to perform the supported test\r
155 //\r
156 Status = gBS->OpenProtocol (\r
157 Controller,\r
158 &gEfiDevicePathProtocolGuid,\r
159 (VOID **) &ParentDevicePath,\r
160 This->DriverBindingHandle,\r
161 Controller,\r
162 EFI_OPEN_PROTOCOL_BY_DRIVER\r
163 );\r
164 if (Status == EFI_ALREADY_STARTED) {\r
165 return EFI_SUCCESS;\r
166 }\r
167\r
168 if (EFI_ERROR (Status)) {\r
169 return Status;\r
170 }\r
171\r
172 gBS->CloseProtocol (\r
173 Controller,\r
174 &gEfiDevicePathProtocolGuid,\r
175 This->DriverBindingHandle,\r
176 Controller\r
177 );\r
178\r
179 //\r
180 // The Controller must support the Serial I/O Protocol.\r
181 // This driver is a bus driver with at most 1 child device, so it is\r
182 // ok for it to be already started.\r
183 //\r
184 Status = gBS->OpenProtocol (\r
185 Controller,\r
186 &gEfiSerialIoProtocolGuid,\r
187 (VOID **) &SerialIo,\r
188 This->DriverBindingHandle,\r
189 Controller,\r
190 EFI_OPEN_PROTOCOL_BY_DRIVER\r
191 );\r
192 if (Status == EFI_ALREADY_STARTED) {\r
193 return EFI_SUCCESS;\r
194 }\r
195\r
196 if (EFI_ERROR (Status)) {\r
197 return Status;\r
198 }\r
199 //\r
200 // Close the I/O Abstraction(s) used to perform the supported test\r
201 //\r
202 gBS->CloseProtocol (\r
203 Controller,\r
204 &gEfiSerialIoProtocolGuid,\r
205 This->DriverBindingHandle,\r
206 Controller\r
207 );\r
208\r
209 return Status;\r
210}\r
211\r
212EFI_STATUS\r
213EFIAPI\r
214TerminalDriverBindingStart (\r
215 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
216 IN EFI_HANDLE Controller,\r
217 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
218 )\r
219/*++\r
220\r
221 Routine Description:\r
222\r
223 Start the controller.\r
224\r
225 Arguments:\r
226\r
227 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
228 Controller - The handle of the controller to start.\r
229 RemainingDevicePath - A pointer to the remaining portion of a devcie path.\r
230\r
231 Returns:\r
232\r
233 EFI_SUCCESS.\r
234\r
235--*/\r
236{\r
237 EFI_STATUS Status;\r
238 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
239 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
240 VENDOR_DEVICE_PATH *Node;\r
241 VENDOR_DEVICE_PATH *DefaultNode;\r
242 EFI_SERIAL_IO_MODE *Mode;\r
243 UINTN SerialInTimeOut;\r
244 TERMINAL_DEV *TerminalDevice;\r
245 UINT8 TerminalType;\r
246 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
247 UINTN EntryCount;\r
248 UINTN Index;\r
249 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
250\r
251 TerminalDevice = NULL;\r
252 DefaultNode = NULL;\r
253 //\r
254 // Get the Device Path Protocol to build the device path of the child device\r
255 //\r
256 Status = gBS->OpenProtocol (\r
257 Controller,\r
258 &gEfiDevicePathProtocolGuid,\r
259 (VOID **) &ParentDevicePath,\r
260 This->DriverBindingHandle,\r
261 Controller,\r
262 EFI_OPEN_PROTOCOL_BY_DRIVER\r
263 );\r
264 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
265 return Status;\r
266 }\r
95276127 267\r
268 //\r
269 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.\r
270 //\r
271 Status = gBS->OpenProtocol (\r
272 Controller,\r
273 &gEfiSerialIoProtocolGuid,\r
274 (VOID **) &SerialIo,\r
275 This->DriverBindingHandle,\r
276 Controller,\r
277 EFI_OPEN_PROTOCOL_BY_DRIVER\r
278 );\r
279 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
280 return Status;\r
281 }\r
282\r
283 if (Status != EFI_ALREADY_STARTED) {\r
284 //\r
285 // If Serial I/O is not already open by this driver, then tag the handle\r
286 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and\r
287 // StdErrDev variables with the list of possible terminal types on this\r
288 // serial port.\r
289 //\r
290 Status = gBS->OpenProtocol (\r
291 Controller,\r
292 &gEfiCallerIdGuid,\r
293 NULL,\r
294 This->DriverBindingHandle,\r
295 Controller,\r
296 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
297 );\r
298 if (EFI_ERROR (Status)) {\r
299 Status = gBS->InstallMultipleProtocolInterfaces (\r
300 &Controller,\r
301 &gEfiCallerIdGuid,\r
302 DuplicateDevicePath (ParentDevicePath),\r
303 NULL\r
304 );\r
305 if (EFI_ERROR (Status)) {\r
306 goto Error;\r
307 }\r
308 //\r
309 // if the serial device is a hot plug device, do not update the\r
310 // ConInDev, ConOutDev, and StdErrDev variables.\r
311 //\r
312 Status = gBS->OpenProtocol (\r
313 Controller,\r
314 &gEfiHotPlugDeviceGuid,\r
315 NULL,\r
316 This->DriverBindingHandle,\r
317 Controller,\r
318 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
319 );\r
320 if (EFI_ERROR (Status)) {\r
ff37790d 321 TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
84ea1415 322 TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
ff37790d 323 TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
95276127 324 }\r
325 }\r
326 }\r
327 //\r
328 // Make sure a child handle does not already exist. This driver can only\r
329 // produce one child per serial port.\r
330 //\r
331 Status = gBS->OpenProtocolInformation (\r
332 Controller,\r
333 &gEfiSerialIoProtocolGuid,\r
334 &OpenInfoBuffer,\r
335 &EntryCount\r
336 );\r
337 if (!EFI_ERROR (Status)) {\r
338 Status = EFI_SUCCESS;\r
339 for (Index = 0; Index < EntryCount; Index++) {\r
340 if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
341 Status = EFI_ALREADY_STARTED;\r
342 }\r
343 }\r
344\r
345 FreePool (OpenInfoBuffer);\r
346 if (EFI_ERROR (Status)) {\r
347 return Status;\r
348 }\r
349 }\r
350 //\r
351 // If RemainingDevicePath is NULL, then create default device path node\r
352 //\r
353 if (RemainingDevicePath == NULL) {\r
6b88ceec 354 DefaultNode = AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH));\r
95276127 355 if (DefaultNode == NULL) {\r
356 Status = EFI_OUT_OF_RESOURCES;\r
357 goto Error;\r
358 }\r
359\r
6b88ceec
A
360 TerminalType = FixedPcdGet8 (PcdDefaultTerminalType);\r
361 // must be between PcAnsiType (0) and VTUTF8Type (3)\r
362 ASSERT (TerminalType <= VTUTF8Type);\r
95276127 363\r
6b88ceec
A
364 CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));\r
365 RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL*)DefaultNode;\r
95276127 366 } else {\r
6b88ceec
A
367 //\r
368 // Use the RemainingDevicePath to determine the terminal type\r
369 //\r
370 Node = (VENDOR_DEVICE_PATH *)RemainingDevicePath;\r
371 if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
372 TerminalType = PcAnsiType;\r
373 } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
374 TerminalType = VT100Type;\r
375 } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
376 TerminalType = VT100PlusType;\r
377 } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
378 TerminalType = VTUTF8Type;\r
379 } else {\r
380 goto Error;\r
381 }\r
95276127 382 }\r
6b88ceec 383\r
95276127 384 //\r
385 // Initialize the Terminal Dev\r
386 //\r
6b88ceec 387 TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &gTerminalDevTemplate);\r
95276127 388 if (TerminalDevice == NULL) {\r
389 Status = EFI_OUT_OF_RESOURCES;\r
390 goto Error;\r
391 }\r
392\r
95276127 393 TerminalDevice->TerminalType = TerminalType;\r
95276127 394 TerminalDevice->SerialIo = SerialIo;\r
395\r
66aa04e4 396 InitializeListHead (&TerminalDevice->NotifyList);\r
397 Status = gBS->CreateEvent (\r
398 EVT_NOTIFY_WAIT,\r
399 TPL_NOTIFY,\r
400 TerminalConInWaitForKeyEx,\r
401 &TerminalDevice->SimpleInputEx,\r
402 &TerminalDevice->SimpleInputEx.WaitForKeyEx\r
403 );\r
404 if (EFI_ERROR (Status)) {\r
405 goto Error;\r
406 }\r
407\r
408\r
95276127 409 Status = gBS->CreateEvent (\r
410 EVT_NOTIFY_WAIT,\r
411 TPL_NOTIFY,\r
412 TerminalConInWaitForKey,\r
413 &TerminalDevice->SimpleInput,\r
414 &TerminalDevice->SimpleInput.WaitForKey\r
415 );\r
416 if (EFI_ERROR (Status)) {\r
417 goto Error;\r
418 }\r
419 //\r
420 // initialize the FIFO buffer used for accommodating\r
421 // the pre-read pending characters\r
422 //\r
423 InitializeRawFiFo (TerminalDevice);\r
424 InitializeUnicodeFiFo (TerminalDevice);\r
425 InitializeEfiKeyFiFo (TerminalDevice);\r
426\r
427 //\r
428 // Set the timeout value of serial buffer for\r
429 // keystroke response performance issue\r
430 //\r
431 Mode = TerminalDevice->SerialIo->Mode;\r
66aa04e4 432\r
95276127 433 SerialInTimeOut = 0;\r
434 if (Mode->BaudRate != 0) {\r
435 SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;\r
436 }\r
437\r
438 Status = TerminalDevice->SerialIo->SetAttributes (\r
439 TerminalDevice->SerialIo,\r
440 Mode->BaudRate,\r
441 Mode->ReceiveFifoDepth,\r
442 (UINT32) SerialInTimeOut,\r
443 (EFI_PARITY_TYPE) (Mode->Parity),\r
444 (UINT8) Mode->DataBits,\r
445 (EFI_STOP_BITS_TYPE) (Mode->StopBits)\r
446 );\r
447 if (EFI_ERROR (Status)) {\r
448 //\r
449 // if set attributes operation fails, invalidate\r
450 // the value of SerialInTimeOut,thus make it\r
451 // inconsistent with the default timeout value\r
452 // of serial buffer. This will invoke the recalculation\r
453 // in the readkeystroke routine.\r
454 //\r
455 TerminalDevice->SerialInTimeOut = 0;\r
456 } else {\r
457 TerminalDevice->SerialInTimeOut = SerialInTimeOut;\r
458 }\r
459 //\r
460 // Build the device path for the child device\r
461 //\r
462 Status = SetTerminalDevicePath (\r
463 TerminalDevice->TerminalType,\r
464 ParentDevicePath,\r
465 &TerminalDevice->DevicePath\r
466 );\r
467 if (EFI_ERROR (Status)) {\r
468 goto Error;\r
469 }\r
470\r
471 DevicePath = TerminalDevice->DevicePath;\r
472\r
473 Status = TerminalDevice->SimpleInput.Reset (\r
474 &TerminalDevice->SimpleInput,\r
475 FALSE\r
476 );\r
477 if (EFI_ERROR (Status)) {\r
478 //\r
479 // Need to report Error Code first\r
480 //\r
481 goto ReportError;\r
482 }\r
483 //\r
484 // Simple Text Output Protocol\r
485 //\r
3012ce5c 486 TerminalDevice->SimpleTextOutput.Reset = TerminalConOutReset;\r
487 TerminalDevice->SimpleTextOutput.OutputString = TerminalConOutOutputString;\r
488 TerminalDevice->SimpleTextOutput.TestString = TerminalConOutTestString;\r
489 TerminalDevice->SimpleTextOutput.QueryMode = TerminalConOutQueryMode;\r
490 TerminalDevice->SimpleTextOutput.SetMode = TerminalConOutSetMode;\r
491 TerminalDevice->SimpleTextOutput.SetAttribute = TerminalConOutSetAttribute;\r
492 TerminalDevice->SimpleTextOutput.ClearScreen = TerminalConOutClearScreen;\r
493 TerminalDevice->SimpleTextOutput.SetCursorPosition = TerminalConOutSetCursorPosition;\r
494 TerminalDevice->SimpleTextOutput.EnableCursor = TerminalConOutEnableCursor;\r
95276127 495 TerminalDevice->SimpleTextOutput.Mode = &TerminalDevice->SimpleTextOutputMode;\r
496\r
7347d5d6 497 TerminalDevice->SimpleTextOutputMode.MaxMode = 3;\r
3012ce5c 498 //\r
499 // For terminal devices, cursor is always visible\r
500 //\r
501 TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;\r
502 Status = TerminalDevice->SimpleTextOutput.SetAttribute (\r
503 &TerminalDevice->SimpleTextOutput,\r
504 EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)\r
505 );\r
506 if (EFI_ERROR (Status)) {\r
507 goto ReportError;\r
508 }\r
509\r
95276127 510 Status = TerminalDevice->SimpleTextOutput.Reset (\r
511 &TerminalDevice->SimpleTextOutput,\r
512 FALSE\r
513 );\r
514 if (EFI_ERROR (Status)) {\r
515 goto ReportError;\r
516 }\r
517\r
518 Status = TerminalDevice->SimpleTextOutput.SetMode (\r
519 &TerminalDevice->SimpleTextOutput,\r
520 0\r
521 );\r
522 if (EFI_ERROR (Status)) {\r
523 goto ReportError;\r
524 }\r
525\r
526 Status = TerminalDevice->SimpleTextOutput.EnableCursor (\r
527 &TerminalDevice->SimpleTextOutput,\r
528 TRUE\r
529 );\r
530 if (EFI_ERROR (Status)) {\r
531 goto ReportError;\r
532 }\r
95276127 533\r
534 Status = gBS->CreateEvent (\r
535 EVT_TIMER,\r
536 TPL_CALLBACK,\r
537 NULL,\r
538 NULL,\r
539 &TerminalDevice->TwoSecondTimeOut\r
540 );\r
541\r
542 //\r
543 // Build the component name for the child device\r
544 //\r
545 TerminalDevice->ControllerNameTable = NULL;\r
546 switch (TerminalDevice->TerminalType) {\r
547 case PcAnsiType:\r
5bca971e 548 AddUnicodeString2 (\r
95276127 549 "eng",\r
550 gTerminalComponentName.SupportedLanguages,\r
551 &TerminalDevice->ControllerNameTable,\r
5bca971e 552 (CHAR16 *)L"PC-ANSI Serial Console",\r
553 TRUE\r
95276127 554 );\r
5bca971e 555 AddUnicodeString2 (\r
556 "en",\r
557 gTerminalComponentName2.SupportedLanguages,\r
558 &TerminalDevice->ControllerNameTable,\r
559 (CHAR16 *)L"PC-ANSI Serial Console",\r
560 FALSE\r
561 );\r
562\r
95276127 563 break;\r
564\r
565 case VT100Type:\r
5bca971e 566 AddUnicodeString2 (\r
95276127 567 "eng",\r
568 gTerminalComponentName.SupportedLanguages,\r
569 &TerminalDevice->ControllerNameTable,\r
5bca971e 570 (CHAR16 *)L"VT-100 Serial Console",\r
571 TRUE\r
95276127 572 );\r
5bca971e 573 AddUnicodeString2 (\r
574 "en",\r
575 gTerminalComponentName2.SupportedLanguages,\r
576 &TerminalDevice->ControllerNameTable,\r
577 (CHAR16 *)L"VT-100 Serial Console",\r
578 FALSE\r
579 );\r
580\r
95276127 581 break;\r
582\r
583 case VT100PlusType:\r
5bca971e 584 AddUnicodeString2 (\r
95276127 585 "eng",\r
586 gTerminalComponentName.SupportedLanguages,\r
587 &TerminalDevice->ControllerNameTable,\r
5bca971e 588 (CHAR16 *)L"VT-100+ Serial Console",\r
589 TRUE\r
95276127 590 );\r
5bca971e 591 AddUnicodeString2 (\r
592 "en",\r
593 gTerminalComponentName2.SupportedLanguages,\r
594 &TerminalDevice->ControllerNameTable,\r
595 (CHAR16 *)L"VT-100+ Serial Console",\r
596 FALSE\r
597 );\r
598\r
95276127 599 break;\r
600\r
601 case VTUTF8Type:\r
5bca971e 602 AddUnicodeString2 (\r
95276127 603 "eng",\r
604 gTerminalComponentName.SupportedLanguages,\r
605 &TerminalDevice->ControllerNameTable,\r
5bca971e 606 (CHAR16 *)L"VT-UTF8 Serial Console",\r
607 TRUE\r
95276127 608 );\r
5bca971e 609 AddUnicodeString2 (\r
610 "en",\r
611 gTerminalComponentName2.SupportedLanguages,\r
612 &TerminalDevice->ControllerNameTable,\r
613 (CHAR16 *)L"VT-UTF8 Serial Console",\r
614 FALSE\r
615 );\r
616\r
95276127 617 break;\r
618 }\r
619 //\r
620 // Install protocol interfaces for the serial device.\r
621 //\r
622 Status = gBS->InstallMultipleProtocolInterfaces (\r
623 &TerminalDevice->Handle,\r
624 &gEfiDevicePathProtocolGuid,\r
625 TerminalDevice->DevicePath,\r
626 &gEfiSimpleTextInProtocolGuid,\r
627 &TerminalDevice->SimpleInput,\r
66aa04e4 628 &gEfiSimpleTextInputExProtocolGuid,\r
629 &TerminalDevice->SimpleInputEx,\r
95276127 630 &gEfiSimpleTextOutProtocolGuid,\r
631 &TerminalDevice->SimpleTextOutput,\r
632 NULL\r
633 );\r
634 if (EFI_ERROR (Status)) {\r
635 goto Error;\r
636 }\r
637 //\r
638 // if the serial device is a hot plug device, attaches the HotPlugGuid\r
639 // onto the terminal device handle.\r
640 //\r
641 Status = gBS->OpenProtocol (\r
642 Controller,\r
643 &gEfiHotPlugDeviceGuid,\r
644 NULL,\r
645 This->DriverBindingHandle,\r
646 Controller,\r
647 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
648 );\r
649 if (!EFI_ERROR (Status)) {\r
650 Status = gBS->InstallMultipleProtocolInterfaces (\r
651 &TerminalDevice->Handle,\r
652 &gEfiHotPlugDeviceGuid,\r
653 NULL,\r
654 NULL\r
655 );\r
656 }\r
657 //\r
658 // Register the Parent-Child relationship via\r
659 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
660 //\r
661 Status = gBS->OpenProtocol (\r
662 Controller,\r
663 &gEfiSerialIoProtocolGuid,\r
664 (VOID **) &TerminalDevice->SerialIo,\r
665 This->DriverBindingHandle,\r
666 TerminalDevice->Handle,\r
667 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
668 );\r
669 if (EFI_ERROR (Status)) {\r
670 goto Error;\r
671 }\r
672\r
673 if (DefaultNode != NULL) {\r
674 FreePool (DefaultNode);\r
675 }\r
676\r
677 return EFI_SUCCESS;\r
678\r
679ReportError:\r
680 //\r
681 // Report error code before exiting\r
682 //\r
683 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
684 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
97a079ed 685 PcdGet32 (PcdStatusCodeValueRemoteConsoleError),\r
95276127 686 DevicePath\r
687 );\r
688\r
689Error:\r
690 //\r
691 // Use the Stop() function to free all resources allocated in Start()\r
692 //\r
693 if (TerminalDevice != NULL) {\r
694\r
695 if (TerminalDevice->Handle != NULL) {\r
696 This->Stop (This, Controller, 1, &TerminalDevice->Handle);\r
697 } else {\r
698\r
699 if (TerminalDevice->TwoSecondTimeOut != NULL) {\r
700 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
701 }\r
702\r
703 if (TerminalDevice->SimpleInput.WaitForKey != NULL) {\r
704 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
705 }\r
706\r
66aa04e4 707 if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {\r
708 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
709 }\r
710\r
711 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
712\r
95276127 713 if (TerminalDevice->ControllerNameTable != NULL) {\r
714 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
715 }\r
716\r
717 if (TerminalDevice->DevicePath != NULL) {\r
718 FreePool (TerminalDevice->DevicePath);\r
719 }\r
720\r
721 FreePool (TerminalDevice);\r
722 }\r
723 }\r
724\r
725 if (DefaultNode != NULL) {\r
726 FreePool (DefaultNode);\r
727 }\r
728\r
729 This->Stop (This, Controller, 0, NULL);\r
730\r
731 return Status;\r
732}\r
733\r
734EFI_STATUS\r
735EFIAPI\r
736TerminalDriverBindingStop (\r
737 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
738 IN EFI_HANDLE Controller,\r
739 IN UINTN NumberOfChildren,\r
740 IN EFI_HANDLE *ChildHandleBuffer\r
741 )\r
742/*++\r
743\r
744 Routine Description:\r
745\r
746 Stop a device controller.\r
747\r
748 Arguments:\r
749\r
750 This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
751 Controller - A handle to the device being stopped.\r
752 NumberOfChildren - The number of child device handles in ChildHandleBuffer.\r
753 ChildHandleBuffer - An array of child handles to be freed.\r
754\r
755 Returns:\r
756\r
757 EFI_SUCCESS - Operation successful.\r
758 EFI_DEVICE_ERROR - Devices error.\r
759\r
760--*/\r
761{\r
762 EFI_STATUS Status;\r
763 UINTN Index;\r
764 BOOLEAN AllChildrenStopped;\r
765 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;\r
766 TERMINAL_DEV *TerminalDevice;\r
767 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
768 EFI_SERIAL_IO_PROTOCOL *SerialIo;\r
769 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
770\r
771 Status = gBS->HandleProtocol (\r
772 Controller,\r
773 &gEfiDevicePathProtocolGuid,\r
774 (VOID **) &DevicePath\r
775 );\r
776 if (EFI_ERROR (Status)) {\r
777 return Status;\r
778 }\r
95276127 779\r
780 //\r
781 // Complete all outstanding transactions to Controller.\r
782 // Don't allow any new transaction to Controller to be started.\r
783 //\r
784 if (NumberOfChildren == 0) {\r
785 //\r
786 // Close the bus driver\r
787 //\r
788 Status = gBS->OpenProtocol (\r
789 Controller,\r
790 &gEfiCallerIdGuid,\r
791 (VOID **) &ParentDevicePath,\r
792 This->DriverBindingHandle,\r
793 Controller,\r
794 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
795 );\r
796 if (!EFI_ERROR (Status)) {\r
797 //\r
798 // Remove Parent Device Path from\r
799 // the Console Device Environment Variables\r
800 //\r
ff37790d
A
801 TerminalRemoveConsoleDevVariable (L"ConInDev", ParentDevicePath);\r
802 TerminalRemoveConsoleDevVariable (L"ConOutDev", ParentDevicePath);\r
803 TerminalRemoveConsoleDevVariable (L"ErrOutDev", ParentDevicePath);\r
95276127 804\r
805 //\r
806 // Uninstall the Terminal Driver's GUID Tag from the Serial controller\r
807 //\r
808 Status = gBS->UninstallMultipleProtocolInterfaces (\r
809 Controller,\r
810 &gEfiCallerIdGuid,\r
811 ParentDevicePath,\r
812 NULL\r
813 );\r
814\r
815 //\r
816 // Free the ParentDevicePath that was duplicated in Start()\r
817 //\r
818 if (!EFI_ERROR (Status)) {\r
819 FreePool (ParentDevicePath);\r
820 }\r
821 }\r
822\r
823 gBS->CloseProtocol (\r
824 Controller,\r
825 &gEfiSerialIoProtocolGuid,\r
826 This->DriverBindingHandle,\r
827 Controller\r
828 );\r
829\r
830 gBS->CloseProtocol (\r
831 Controller,\r
832 &gEfiDevicePathProtocolGuid,\r
833 This->DriverBindingHandle,\r
834 Controller\r
835 );\r
836\r
837 return EFI_SUCCESS;\r
838 }\r
839\r
840 AllChildrenStopped = TRUE;\r
841\r
842 for (Index = 0; Index < NumberOfChildren; Index++) {\r
843\r
844 Status = gBS->OpenProtocol (\r
845 ChildHandleBuffer[Index],\r
846 &gEfiSimpleTextOutProtocolGuid,\r
847 (VOID **) &SimpleTextOutput,\r
848 This->DriverBindingHandle,\r
849 ChildHandleBuffer[Index],\r
850 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
851 );\r
852 if (!EFI_ERROR (Status)) {\r
853\r
854 TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);\r
855\r
856 gBS->CloseProtocol (\r
857 Controller,\r
858 &gEfiSerialIoProtocolGuid,\r
859 This->DriverBindingHandle,\r
860 ChildHandleBuffer[Index]\r
861 );\r
862\r
863 Status = gBS->UninstallMultipleProtocolInterfaces (\r
864 ChildHandleBuffer[Index],\r
865 &gEfiSimpleTextInProtocolGuid,\r
866 &TerminalDevice->SimpleInput,\r
66aa04e4 867 &gEfiSimpleTextInputExProtocolGuid,\r
868 &TerminalDevice->SimpleInputEx,\r
95276127 869 &gEfiSimpleTextOutProtocolGuid,\r
870 &TerminalDevice->SimpleTextOutput,\r
871 &gEfiDevicePathProtocolGuid,\r
872 TerminalDevice->DevicePath,\r
873 NULL\r
874 );\r
875 if (EFI_ERROR (Status)) {\r
876 gBS->OpenProtocol (\r
877 Controller,\r
878 &gEfiSerialIoProtocolGuid,\r
879 (VOID **) &SerialIo,\r
880 This->DriverBindingHandle,\r
881 ChildHandleBuffer[Index],\r
882 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
883 );\r
884 } else {\r
885\r
886 if (TerminalDevice->ControllerNameTable != NULL) {\r
887 FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);\r
888 }\r
889\r
890 Status = gBS->OpenProtocol (\r
891 ChildHandleBuffer[Index],\r
892 &gEfiHotPlugDeviceGuid,\r
893 NULL,\r
894 This->DriverBindingHandle,\r
895 Controller,\r
896 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
897 );\r
898 if (!EFI_ERROR (Status)) {\r
899 Status = gBS->UninstallMultipleProtocolInterfaces (\r
900 ChildHandleBuffer[Index],\r
901 &gEfiHotPlugDeviceGuid,\r
902 NULL,\r
903 NULL\r
904 );\r
905 } else {\r
906 Status = EFI_SUCCESS;\r
907 }\r
908\r
909 gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);\r
910 gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);\r
66aa04e4 911 gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);\r
912 TerminalFreeNotifyList (&TerminalDevice->NotifyList);\r
95276127 913 FreePool (TerminalDevice->DevicePath);\r
914 FreePool (TerminalDevice);\r
915 }\r
916 }\r
917\r
918 if (EFI_ERROR (Status)) {\r
919 AllChildrenStopped = FALSE;\r
920 }\r
921 }\r
922\r
923 if (!AllChildrenStopped) {\r
924 return EFI_DEVICE_ERROR;\r
925 }\r
926\r
927 return EFI_SUCCESS;\r
928}\r
929\r
66aa04e4 930STATIC\r
931EFI_STATUS\r
932TerminalFreeNotifyList (\r
933 IN OUT LIST_ENTRY *ListHead\r
934 )\r
935/*++\r
936\r
937Routine Description:\r
938\r
939Arguments:\r
940\r
941 ListHead - The list head\r
942\r
943Returns:\r
944\r
945 EFI_SUCCESS - Free the notify list successfully\r
946 EFI_INVALID_PARAMETER - ListHead is invalid.\r
947\r
948--*/\r
949{\r
950 TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
951\r
952 if (ListHead == NULL) {\r
953 return EFI_INVALID_PARAMETER;\r
954 }\r
955 while (!IsListEmpty (ListHead)) {\r
956 NotifyNode = CR (\r
fb0b259e 957 ListHead->ForwardLink,\r
958 TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
959 NotifyEntry,\r
66aa04e4 960 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
961 );\r
962 RemoveEntryList (ListHead->ForwardLink);\r
963 gBS->FreePool (NotifyNode);\r
964 }\r
fb0b259e 965\r
66aa04e4 966 return EFI_SUCCESS;\r
967}\r
968\r
969\r
970\r
95276127 971VOID\r
972TerminalUpdateConsoleDevVariable (\r
973 IN CHAR16 *VariableName,\r
974 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
975 )\r
976{\r
977 EFI_STATUS Status;\r
978 UINTN VariableSize;\r
979 UINT8 TerminalType;\r
980 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
981 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
982 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
983\r
984 Variable = NULL;\r
985\r
986 //\r
987 // Get global variable and its size according to the name given.\r
988 //\r
989 Variable = TerminalGetVariableAndSize (\r
990 VariableName,\r
991 &gEfiGlobalVariableGuid,\r
992 &VariableSize\r
993 );\r
994 //\r
995 // Append terminal device path onto the variable.\r
996 //\r
997 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
998 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
999 NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
1000 if (Variable != NULL) {\r
1001 FreePool (Variable);\r
1002 }\r
1003\r
1004 if (TempDevicePath != NULL) {\r
1005 FreePool (TempDevicePath);\r
1006 }\r
1007\r
1008 Variable = NewVariable;\r
1009 }\r
1010\r
1011 VariableSize = GetDevicePathSize (Variable);\r
1012\r
1013 Status = gRT->SetVariable (\r
1014 VariableName,\r
1015 &gEfiGlobalVariableGuid,\r
1016 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1017 VariableSize,\r
1018 Variable\r
1019 );\r
1020 ASSERT_EFI_ERROR (Status);\r
1021 FreePool (Variable);\r
1022\r
1023 return ;\r
1024}\r
1025\r
1026VOID\r
1027TerminalRemoveConsoleDevVariable (\r
1028 IN CHAR16 *VariableName,\r
1029 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath\r
1030 )\r
1031/*++\r
1032\r
1033 Routine Description:\r
1034\r
1035 Remove console device variable.\r
1036\r
1037 Arguments:\r
1038\r
1039 VariableName - A pointer to the variable name.\r
1040 ParentDevicePath - A pointer to the parent device path.\r
1041\r
1042 Returns:\r
1043\r
1044--*/\r
1045{\r
1046 EFI_STATUS Status;\r
1047 BOOLEAN FoundOne;\r
1048 BOOLEAN Match;\r
1049 UINTN VariableSize;\r
1050 UINTN InstanceSize;\r
1051 UINT8 TerminalType;\r
1052 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
1053 EFI_DEVICE_PATH_PROTOCOL *Variable;\r
1054 EFI_DEVICE_PATH_PROTOCOL *OriginalVariable;\r
1055 EFI_DEVICE_PATH_PROTOCOL *NewVariable;\r
1056 EFI_DEVICE_PATH_PROTOCOL *SavedNewVariable;\r
1057 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1058\r
1059 Variable = NULL;\r
1060 Instance = NULL;\r
1061\r
1062 //\r
1063 // Get global variable and its size according to the name given.\r
1064 //\r
1065 Variable = TerminalGetVariableAndSize (\r
1066 VariableName,\r
1067 &gEfiGlobalVariableGuid,\r
1068 &VariableSize\r
1069 );\r
1070 if (Variable == NULL) {\r
1071 return ;\r
1072 }\r
1073\r
1074 FoundOne = FALSE;\r
1075 OriginalVariable = Variable;\r
1076 NewVariable = NULL;\r
1077\r
1078 //\r
1079 // Get first device path instance from Variable\r
1080 //\r
1081 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1082 if (Instance == NULL) {\r
1083 FreePool (OriginalVariable);\r
1084 return ;\r
1085 }\r
1086 //\r
1087 // Loop through all the device path instances of Variable\r
1088 //\r
1089 do {\r
1090 //\r
1091 // Loop through all the terminal types that this driver supports\r
1092 //\r
1093 Match = FALSE;\r
1094 for (TerminalType = PcAnsiType; TerminalType <= VTUTF8Type; TerminalType++) {\r
1095\r
1096 SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
1097\r
1098 //\r
1099 // Compare the genterated device path to the current device path instance\r
1100 //\r
1101 if (TempDevicePath != NULL) {\r
1102 if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {\r
1103 Match = TRUE;\r
1104 FoundOne = TRUE;\r
1105 }\r
1106\r
1107 FreePool (TempDevicePath);\r
1108 }\r
1109 }\r
1110 //\r
1111 // If a match was not found, then keep the current device path instance\r
1112 //\r
1113 if (!Match) {\r
1114 SavedNewVariable = NewVariable;\r
1115 NewVariable = AppendDevicePathInstance (NewVariable, Instance);\r
1116 if (SavedNewVariable != NULL) {\r
1117 FreePool (SavedNewVariable);\r
1118 }\r
1119 }\r
1120 //\r
1121 // Get next device path instance from Variable\r
1122 //\r
1123 FreePool (Instance);\r
1124 Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);\r
1125 } while (Instance != NULL);\r
1126\r
1127 FreePool (OriginalVariable);\r
1128\r
1129 if (FoundOne) {\r
1130 VariableSize = GetDevicePathSize (NewVariable);\r
1131\r
1132 Status = gRT->SetVariable (\r
1133 VariableName,\r
1134 &gEfiGlobalVariableGuid,\r
1135 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
1136 VariableSize,\r
1137 NewVariable\r
1138 );\r
1139 ASSERT_EFI_ERROR (Status);\r
1140 }\r
1141\r
1142 if (NewVariable != NULL) {\r
1143 FreePool (NewVariable);\r
1144 }\r
1145\r
1146 return ;\r
1147}\r
1148\r
1149VOID *\r
1150TerminalGetVariableAndSize (\r
1151 IN CHAR16 *Name,\r
1152 IN EFI_GUID *VendorGuid,\r
1153 OUT UINTN *VariableSize\r
1154 )\r
1155/*++\r
1156\r
1157Routine Description:\r
1158 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
1159 buffer, and the size of the buffer. On failure return NULL.\r
1160\r
1161Arguments:\r
1162 Name - String part of EFI variable name\r
1163\r
1164 VendorGuid - GUID part of EFI variable name\r
1165\r
1166 VariableSize - Returns the size of the EFI variable that was read\r
1167\r
1168Returns:\r
1169 Dynamically allocated memory that contains a copy of the EFI variable.\r
1170 Caller is repsoncible freeing the buffer.\r
1171\r
1172 NULL - Variable was not read\r
1173\r
1174--*/\r
1175{\r
1176 EFI_STATUS Status;\r
1177 UINTN BufferSize;\r
1178 VOID *Buffer;\r
1179\r
1180 Buffer = NULL;\r
1181\r
1182 //\r
1183 // Pass in a small size buffer to find the actual variable size.\r
1184 //\r
1185 BufferSize = 1;\r
1186 Buffer = AllocatePool (BufferSize);\r
1187 if (Buffer == NULL) {\r
1188 *VariableSize = 0;\r
1189 return NULL;\r
1190 }\r
1191\r
1192 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1193\r
1194 if (Status == EFI_SUCCESS) {\r
1195 *VariableSize = BufferSize;\r
1196 return Buffer;\r
1197\r
1198 } else if (Status == EFI_BUFFER_TOO_SMALL) {\r
1199 //\r
1200 // Allocate the buffer to return\r
1201 //\r
1202 FreePool (Buffer);\r
1203 Buffer = AllocatePool (BufferSize);\r
1204 if (Buffer == NULL) {\r
1205 *VariableSize = 0;\r
1206 return NULL;\r
1207 }\r
1208 //\r
1209 // Read variable into the allocated buffer.\r
1210 //\r
1211 Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
1212 if (EFI_ERROR (Status)) {\r
1213 BufferSize = 0;\r
1214 FreePool (Buffer);\r
1215 Buffer = NULL;\r
1216 }\r
1217 } else {\r
1218 //\r
1219 // Variable not found or other errors met.\r
1220 //\r
1221 BufferSize = 0;\r
1222 FreePool (Buffer);\r
1223 Buffer = NULL;\r
1224 }\r
1225\r
1226 *VariableSize = BufferSize;\r
1227 return Buffer;\r
1228}\r
1229\r
1230EFI_STATUS\r
1231SetTerminalDevicePath (\r
1232 IN UINT8 TerminalType,\r
1233 IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
1234 OUT EFI_DEVICE_PATH_PROTOCOL **TerminalDevicePath\r
1235 )\r
1236{\r
1237 VENDOR_DEVICE_PATH Node;\r
1238\r
1239 *TerminalDevicePath = NULL;\r
1240 Node.Header.Type = MESSAGING_DEVICE_PATH;\r
1241 Node.Header.SubType = MSG_VENDOR_DP;\r
1242\r
1243 //\r
1244 // generate terminal device path node according to terminal type.\r
1245 //\r
1246 switch (TerminalType) {\r
1247\r
1248 case PcAnsiType:\r
1249 CopyMem (\r
1250 &Node.Guid,\r
1251 &gEfiPcAnsiGuid,\r
1252 sizeof (EFI_GUID)\r
1253 );\r
1254 break;\r
1255\r
1256 case VT100Type:\r
1257 CopyMem (\r
1258 &Node.Guid,\r
1259 &gEfiVT100Guid,\r
1260 sizeof (EFI_GUID)\r
1261 );\r
1262 break;\r
1263\r
1264 case VT100PlusType:\r
1265 CopyMem (\r
1266 &Node.Guid,\r
1267 &gEfiVT100PlusGuid,\r
1268 sizeof (EFI_GUID)\r
1269 );\r
1270 break;\r
1271\r
1272 case VTUTF8Type:\r
1273 CopyMem (\r
1274 &Node.Guid,\r
1275 &gEfiVTUTF8Guid,\r
1276 sizeof (EFI_GUID)\r
1277 );\r
1278 break;\r
1279\r
1280 default:\r
1281 return EFI_UNSUPPORTED;\r
1282 break;\r
1283 }\r
1284\r
1285 SetDevicePathNodeLength (\r
1286 &Node.Header,\r
1287 sizeof (VENDOR_DEVICE_PATH)\r
1288 );\r
1289 //\r
1290 // append the terminal node onto parent device path\r
1291 // to generate a complete terminal device path.\r
1292 //\r
1293 *TerminalDevicePath = AppendDevicePathNode (\r
1294 ParentDevicePath,\r
1295 (EFI_DEVICE_PATH_PROTOCOL *) &Node\r
1296 );\r
1297 if (*TerminalDevicePath == NULL) {\r
1298 return EFI_OUT_OF_RESOURCES;\r
1299 }\r
1300\r
1301 return EFI_SUCCESS;\r
1302}\r
1303\r
1304VOID\r
1305InitializeRawFiFo (\r
1306 IN TERMINAL_DEV *TerminalDevice\r
1307 )\r
1308{\r
1309 //\r
1310 // Make the raw fifo empty.\r
1311 //\r
1312 TerminalDevice->RawFiFo.Head = TerminalDevice->RawFiFo.Tail;\r
1313}\r
1314\r
1315VOID\r
1316InitializeUnicodeFiFo (\r
1317 IN TERMINAL_DEV *TerminalDevice\r
1318 )\r
1319{\r
1320 //\r
1321 // Make the unicode fifo empty\r
1322 //\r
1323 TerminalDevice->UnicodeFiFo.Head = TerminalDevice->UnicodeFiFo.Tail;\r
1324}\r
1325\r
1326VOID\r
1327InitializeEfiKeyFiFo (\r
1328 IN TERMINAL_DEV *TerminalDevice\r
1329 )\r
1330{\r
1331 //\r
1332 // Make the efi key fifo empty\r
1333 //\r
1334 TerminalDevice->EfiKeyFiFo.Head = TerminalDevice->EfiKeyFiFo.Tail;\r
1335}\r
97a079ed
A
1336\r
1337\r
1338/**\r
1339 The user Entry Point for module Terminal. The user code starts with this function.\r
1340\r
fb0b259e 1341 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
97a079ed 1342 @param[in] SystemTable A pointer to the EFI System Table.\r
fb0b259e 1343\r
97a079ed
A
1344 @retval EFI_SUCCESS The entry point is executed successfully.\r
1345 @retval other Some error occurs when executing this entry point.\r
1346\r
1347**/\r
1348EFI_STATUS\r
1349EFIAPI\r
1350InitializeTerminal(\r
1351 IN EFI_HANDLE ImageHandle,\r
1352 IN EFI_SYSTEM_TABLE *SystemTable\r
1353 )\r
1354{\r
1355 EFI_STATUS Status;\r
1356\r
1357 //\r
1358 // Install driver model protocol(s).\r
1359 //\r
5bca971e 1360 Status = EfiLibInstallDriverBindingComponentName2 (\r
97a079ed
A
1361 ImageHandle,\r
1362 SystemTable,\r
1363 &gTerminalDriverBinding,\r
1364 ImageHandle,\r
1365 &gTerminalComponentName,\r
5bca971e 1366 &gTerminalComponentName2\r
97a079ed
A
1367 );\r
1368 ASSERT_EFI_ERROR (Status);\r
1369\r
1370\r
1371 return Status;\r
1372}\r