]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - SimpleTextInOut.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SimpleTextInOut.c
... / ...
CommitLineData
1/** @file\r
2 Simple Console that sits on a SerialLib.\r
3\r
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16/*\r
17 Symbols used in table below\r
18===========================\r
19 ESC = 0x1B\r
20 CSI = 0x9B\r
21 DEL = 0x7f\r
22 ^ = CTRL\r
23\r
24+=========+======+===========+==========+==========+\r
25| | EFI | UEFI 2.0 | | |\r
26| | Scan | | VT100+ | |\r
27| KEY | Code | PC ANSI | VTUTF8 | VT100 |\r
28+=========+======+===========+==========+==========+\r
29| NULL | 0x00 | | | |\r
30| UP | 0x01 | ESC [ A | ESC [ A | ESC [ A |\r
31| DOWN | 0x02 | ESC [ B | ESC [ B | ESC [ B |\r
32| RIGHT | 0x03 | ESC [ C | ESC [ C | ESC [ C |\r
33| LEFT | 0x04 | ESC [ D | ESC [ D | ESC [ D |\r
34| HOME | 0x05 | ESC [ H | ESC h | ESC [ H |\r
35| END | 0x06 | ESC [ F | ESC k | ESC [ K |\r
36| INSERT | 0x07 | ESC [ @ | ESC + | ESC [ @ |\r
37| | | ESC [ L | | ESC [ L |\r
38| DELETE | 0x08 | ESC [ X | ESC - | ESC [ P |\r
39| PG UP | 0x09 | ESC [ I | ESC ? | ESC [ V |\r
40| | | | | ESC [ ? |\r
41| PG DOWN | 0x0A | ESC [ G | ESC / | ESC [ U |\r
42| | | | | ESC [ / |\r
43| F1 | 0x0B | ESC [ M | ESC 1 | ESC O P |\r
44| F2 | 0x0C | ESC [ N | ESC 2 | ESC O Q |\r
45| F3 | 0x0D | ESC [ O | ESC 3 | ESC O w |\r
46| F4 | 0x0E | ESC [ P | ESC 4 | ESC O x |\r
47| F5 | 0x0F | ESC [ Q | ESC 5 | ESC O t |\r
48| F6 | 0x10 | ESC [ R | ESC 6 | ESC O u |\r
49| F7 | 0x11 | ESC [ S | ESC 7 | ESC O q |\r
50| F8 | 0x12 | ESC [ T | ESC 8 | ESC O r |\r
51| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |\r
52| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |\r
53| Escape | 0x17 | ESC | ESC | ESC |\r
54| F11 | 0x15 | | ESC ! | |\r
55| F12 | 0x16 | | ESC @ | |\r
56+=========+======+===========+==========+==========+\r
57\r
58*/\r
59\r
60#include <PiDxe.h>\r
61#include <Library/UefiLib.h>\r
62#include <Library/UefiBootServicesTableLib.h>\r
63#include <Library/BaseLib.h>\r
64#include <Library/MemoryAllocationLib.h>\r
65#include <Library/DebugLib.h>\r
66#include <Library/SerialPortLib.h>\r
67#include <Library/PcdLib.h>\r
68\r
69#include <Protocol/SerialIo.h>\r
70#include <Protocol/SimpleTextIn.h>\r
71#include <Protocol/SimpleTextOut.h>\r
72#include <Protocol/DevicePath.h>\r
73\r
74\r
75#define MODE0_COLUMN_COUNT 80\r
76#define MODE0_ROW_COUNT 25\r
77\r
78\r
79EFI_STATUS\r
80EFIAPI\r
81TextInReset(\r
82 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
83 IN BOOLEAN ExtendedVerification\r
84 );\r
85\r
86\r
87EFI_STATUS\r
88EFIAPI\r
89ReadKeyStroke(\r
90 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
91 OUT EFI_INPUT_KEY *Key\r
92 );\r
93\r
94\r
95EFI_STATUS\r
96EFIAPI\r
97TextOutReset(\r
98 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
99 IN BOOLEAN ExtendedVerification\r
100 );\r
101\r
102CHAR8 *\r
103EFIAPI\r
104SafeUnicodeStrToAsciiStr (\r
105 IN CONST CHAR16 *Source,\r
106 OUT CHAR8 *Destination\r
107 );\r
108\r
109EFI_STATUS\r
110EFIAPI\r
111OutputString (\r
112 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
113 IN CHAR16 *String\r
114 );\r
115\r
116\r
117EFI_STATUS\r
118EFIAPI\r
119TestString (\r
120 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
121 IN CHAR16 *String\r
122 );\r
123\r
124\r
125EFI_STATUS\r
126EFIAPI\r
127QueryMode (\r
128 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
129 IN UINTN ModeNumber,\r
130 OUT UINTN *Columns,\r
131 OUT UINTN *Rows\r
132 );\r
133\r
134\r
135EFI_STATUS\r
136EFIAPI\r
137SetMode(\r
138 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
139 IN UINTN ModeNumber\r
140 );\r
141\r
142\r
143EFI_STATUS\r
144EFIAPI\r
145SetAttribute(\r
146 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
147 IN UINTN Attribute\r
148 );\r
149\r
150\r
151EFI_STATUS\r
152EFIAPI\r
153ClearScreen (\r
154 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
155 );\r
156\r
157\r
158EFI_STATUS\r
159EFIAPI\r
160SetCursorPosition (\r
161 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
162 IN UINTN Column,\r
163 IN UINTN Row\r
164 );\r
165\r
166\r
167EFI_STATUS\r
168EFIAPI\r
169EnableCursor (\r
170 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
171 IN BOOLEAN Enable\r
172 );\r
173\r
174\r
175 EFI_SIMPLE_TEXT_INPUT_PROTOCOL mSimpleTextIn = {\r
176 TextInReset,\r
177 ReadKeyStroke,\r
178 NULL\r
179};\r
180\r
181 EFI_SIMPLE_TEXT_OUTPUT_MODE mSimpleTextOutMode = {\r
182 1,\r
183 0,\r
184 EFI_TEXT_ATTR( EFI_LIGHTGRAY, EFI_BLACK ),\r
185 0,\r
186 0,\r
187 TRUE\r
188};\r
189\r
190EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mSimpleTextOut = {\r
191 TextOutReset,\r
192 OutputString,\r
193 TestString,\r
194 QueryMode,\r
195 SetMode,\r
196 SetAttribute,\r
197 ClearScreen,\r
198 SetCursorPosition,\r
199 EnableCursor,\r
200 &mSimpleTextOutMode\r
201};\r
202\r
203EFI_HANDLE mInstallHandle = NULL;\r
204\r
205typedef struct {\r
206 VENDOR_DEVICE_PATH Guid;\r
207 UART_DEVICE_PATH Uart;\r
208 EFI_DEVICE_PATH_PROTOCOL End;\r
209} SIMPLE_TEXT_OUT_DEVICE_PATH;\r
210\r
211SIMPLE_TEXT_OUT_DEVICE_PATH mDevicePath = {\r
212 {\r
213 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },\r
214 EFI_CALLER_ID_GUID\r
215 },\r
216 {\r
217 { MESSAGING_DEVICE_PATH, MSG_UART_DP, { sizeof (UART_DEVICE_PATH), 0} },\r
218 0, // Reserved\r
219 FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate\r
220 FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits\r
221 FixedPcdGet8 (PcdUartDefaultParity), // Parity (N)\r
222 FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits\r
223 },\r
224 { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }\r
225};\r
226\r
227\r
228\r
229\r
230BOOLEAN\r
231TextOutIsValidAscii (\r
232 IN CHAR16 Ascii\r
233 )\r
234{\r
235 //\r
236 // valid ASCII code lies in the extent of 0x20 - 0x7F\r
237 //\r
238 if ((Ascii >= 0x20) && (Ascii <= 0x7F)) {\r
239 return TRUE;\r
240 }\r
241\r
242 return FALSE;\r
243}\r
244\r
245\r
246BOOLEAN\r
247TextOutIsValidEfiCntlChar (\r
248 IN CHAR16 Char\r
249 )\r
250{\r
251 //\r
252 // only support four control characters.\r
253 //\r
254 if (Char == CHAR_NULL ||\r
255 Char == CHAR_BACKSPACE ||\r
256 Char == CHAR_LINEFEED ||\r
257 Char == CHAR_CARRIAGE_RETURN ||\r
258 Char == CHAR_TAB ) {\r
259 return TRUE;\r
260 }\r
261\r
262 return FALSE;\r
263}\r
264\r
265\r
266VOID\r
267EFIAPI\r
268WaitForKeyEvent (\r
269 IN EFI_EVENT Event,\r
270 IN VOID *Context\r
271 )\r
272{\r
273 if (SerialPortPoll ()) {\r
274 gBS->SignalEvent (Event);\r
275 }\r
276}\r
277\r
278\r
279EFI_STATUS\r
280EFIAPI\r
281TextInReset (\r
282 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
283 IN BOOLEAN ExtendedVerification\r
284 )\r
285{\r
286 return EFI_SUCCESS;\r
287}\r
288\r
289\r
290EFI_STATUS\r
291EFIAPI\r
292ReadKeyStroke (\r
293 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
294 OUT EFI_INPUT_KEY *Key\r
295 )\r
296{\r
297 CHAR8 Char;\r
298\r
299 if (!SerialPortPoll ()) {\r
300 return EFI_NOT_READY;\r
301 }\r
302\r
303 SerialPortRead ((UINT8 *)&Char, 1);\r
304\r
305 //\r
306 // Check for ESC sequence. This code is not techincally correct VT100 code.\r
307 // An illegal ESC sequence represents an ESC and the characters that follow.\r
308 // This code will eat one or two chars after an escape. This is done to\r
309 // prevent some complex FIFOing of the data. It is good enough to get\r
310 // the arrow and delete keys working\r
311 //\r
312 Key->UnicodeChar = 0;\r
313 Key->ScanCode = SCAN_NULL;\r
314 if (Char == 0x1b) {\r
315 SerialPortRead ((UINT8 *)&Char, 1);\r
316 if (Char == '[') {\r
317 SerialPortRead ((UINT8 *)&Char, 1);\r
318 switch (Char) {\r
319 case 'A':\r
320 Key->ScanCode = SCAN_UP;\r
321 break;\r
322 case 'B':\r
323 Key->ScanCode = SCAN_DOWN;\r
324 break;\r
325 case 'C':\r
326 Key->ScanCode = SCAN_RIGHT;\r
327 break;\r
328 case 'D':\r
329 Key->ScanCode = SCAN_LEFT;\r
330 break;\r
331 case 'H':\r
332 Key->ScanCode = SCAN_HOME;\r
333 break;\r
334 case 'K':\r
335 case 'F': // PC ANSI\r
336 Key->ScanCode = SCAN_END;\r
337 break;\r
338 case '@':\r
339 case 'L':\r
340 Key->ScanCode = SCAN_INSERT;\r
341 break;\r
342 case 'P':\r
343 case 'X': // PC ANSI\r
344 Key->ScanCode = SCAN_DELETE;\r
345 break;\r
346 case 'U':\r
347 case '/':\r
348 case 'G': // PC ANSI\r
349 Key->ScanCode = SCAN_PAGE_DOWN;\r
350 break;\r
351 case 'V':\r
352 case '?':\r
353 case 'I': // PC ANSI\r
354 Key->ScanCode = SCAN_PAGE_UP;\r
355 break;\r
356\r
357 // PCANSI that does not conflict with VT100\r
358 case 'M':\r
359 Key->ScanCode = SCAN_F1;\r
360 break;\r
361 case 'N':\r
362 Key->ScanCode = SCAN_F2;\r
363 break;\r
364 case 'O':\r
365 Key->ScanCode = SCAN_F3;\r
366 break;\r
367 case 'Q':\r
368 Key->ScanCode = SCAN_F5;\r
369 break;\r
370 case 'R':\r
371 Key->ScanCode = SCAN_F6;\r
372 break;\r
373 case 'S':\r
374 Key->ScanCode = SCAN_F7;\r
375 break;\r
376 case 'T':\r
377 Key->ScanCode = SCAN_F8;\r
378 break;\r
379\r
380 default:\r
381 Key->UnicodeChar = Char;\r
382 break;\r
383 }\r
384 } else if (Char == '0') {\r
385 SerialPortRead ((UINT8 *)&Char, 1);\r
386 switch (Char) {\r
387 case 'P':\r
388 Key->ScanCode = SCAN_F1;\r
389 break;\r
390 case 'Q':\r
391 Key->ScanCode = SCAN_F2;\r
392 break;\r
393 case 'w':\r
394 Key->ScanCode = SCAN_F3;\r
395 break;\r
396 case 'x':\r
397 Key->ScanCode = SCAN_F4;\r
398 break;\r
399 case 't':\r
400 Key->ScanCode = SCAN_F5;\r
401 break;\r
402 case 'u':\r
403 Key->ScanCode = SCAN_F6;\r
404 break;\r
405 case 'q':\r
406 Key->ScanCode = SCAN_F7;\r
407 break;\r
408 case 'r':\r
409 Key->ScanCode = SCAN_F8;\r
410 break;\r
411 case 'p':\r
412 Key->ScanCode = SCAN_F9;\r
413 break;\r
414 case 'm':\r
415 Key->ScanCode = SCAN_F10;\r
416 break;\r
417 default :\r
418 break;\r
419 }\r
420 }\r
421 } else if (Char < ' ') {\r
422 if ((Char == CHAR_BACKSPACE) ||\r
423 (Char == CHAR_TAB) ||\r
424 (Char == CHAR_LINEFEED) ||\r
425 (Char == CHAR_CARRIAGE_RETURN)) {\r
426 // Only let through EFI required control characters\r
427 Key->UnicodeChar = (CHAR16)Char;\r
428 }\r
429 } else if (Char == 0x7f) {\r
430 Key->ScanCode = SCAN_DELETE;\r
431 } else {\r
432 Key->UnicodeChar = (CHAR16)Char;\r
433 }\r
434\r
435 return EFI_SUCCESS;\r
436}\r
437\r
438\r
439EFI_STATUS\r
440EFIAPI\r
441TextOutReset (\r
442 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
443 IN BOOLEAN ExtendedVerification\r
444 )\r
445{\r
446 EFI_STATUS Status;\r
447\r
448 This->SetAttribute(\r
449 This,\r
450 EFI_TEXT_ATTR(This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK)\r
451 );\r
452\r
453 Status = This->SetMode (This, 0);\r
454\r
455 return Status;\r
456}\r
457\r
458CHAR8 *\r
459EFIAPI\r
460SafeUnicodeStrToAsciiStr (\r
461 IN CONST CHAR16 *Source,\r
462 OUT CHAR8 *Destination\r
463 )\r
464{\r
465 CHAR8 *ReturnValue;\r
466\r
467 ASSERT (Destination != NULL);\r
468\r
469 //\r
470 // ASSERT if Source is long than PcdMaximumUnicodeStringLength.\r
471 // Length tests are performed inside StrLen().\r
472 //\r
473 ASSERT (StrSize (Source) != 0);\r
474\r
475 //\r
476 // Source and Destination should not overlap\r
477 //\r
478 ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source));\r
479 ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));\r
480\r
481\r
482 ReturnValue = Destination;\r
483 while (*Source != '\0') {\r
484 //\r
485 // If any non-ascii characters in Source then replace it with '?'.\r
486 //\r
487 if (*Source < 0x80) {\r
488 *Destination = (CHAR8) *Source;\r
489 } else {\r
490 *Destination = '?';\r
491\r
492 //Surrogate pair check.\r
493 if ((*Source >= 0xD800) && (*Source <= 0xDFFF)) {\r
494 Source++;\r
495 }\r
496 }\r
497\r
498 Destination++;\r
499 Source++;\r
500 }\r
501\r
502 *Destination = '\0';\r
503\r
504 //\r
505 // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.\r
506 // Length tests are performed inside AsciiStrLen().\r
507 //\r
508 ASSERT (AsciiStrSize (ReturnValue) != 0);\r
509\r
510 return ReturnValue;\r
511}\r
512\r
513EFI_STATUS\r
514EFIAPI\r
515OutputString (\r
516 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
517 IN CHAR16 *String\r
518 )\r
519{\r
520 UINTN Size;\r
521 CHAR8* OutputString;\r
522 EFI_STATUS Status;\r
523 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
524 UINTN MaxColumn;\r
525 UINTN MaxRow;\r
526\r
527 Size = StrLen(String) + 1;\r
528 OutputString = AllocatePool(Size);\r
529\r
530 //If there is any non-ascii characters in String buffer then replace it with '?'\r
531 //Eventually, UnicodeStrToAsciiStr API should be fixed.\r
532 SafeUnicodeStrToAsciiStr(String, OutputString);\r
533 SerialPortWrite ((UINT8 *)OutputString, Size - 1);\r
534\r
535 //\r
536 // Parse each character of the string to output\r
537 // to update the cursor position information\r
538 //\r
539 Mode = This->Mode;\r
540\r
541 Status = This->QueryMode (\r
542 This,\r
543 Mode->Mode,\r
544 &MaxColumn,\r
545 &MaxRow\r
546 );\r
547 if (EFI_ERROR (Status)) {\r
548 return Status;\r
549 }\r
550\r
551 for (; *String != CHAR_NULL; String++) {\r
552\r
553 switch (*String) {\r
554 case CHAR_BACKSPACE:\r
555 if (Mode->CursorColumn > 0) {\r
556 Mode->CursorColumn--;\r
557 }\r
558 break;\r
559\r
560 case CHAR_LINEFEED:\r
561 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
562 Mode->CursorRow++;\r
563 }\r
564 break;\r
565\r
566 case CHAR_CARRIAGE_RETURN:\r
567 Mode->CursorColumn = 0;\r
568 break;\r
569\r
570 default:\r
571 if (Mode->CursorColumn >= (INT32) (MaxColumn - 1)) {\r
572 // Move the cursor as if we print CHAR_CARRIAGE_RETURN & CHAR_LINE_FEED\r
573 // CHAR_LINEFEED\r
574 if (Mode->CursorRow < (INT32) (MaxRow - 1)) {\r
575 Mode->CursorRow++;\r
576 }\r
577 // CHAR_CARIAGE_RETURN\r
578 Mode->CursorColumn = 0;\r
579 } else {\r
580 Mode->CursorColumn++;\r
581 }\r
582 break;\r
583 }\r
584 }\r
585\r
586 FreePool(OutputString);\r
587\r
588 return EFI_SUCCESS;\r
589}\r
590\r
591\r
592EFI_STATUS\r
593EFIAPI\r
594TestString (\r
595 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
596 IN CHAR16 *String\r
597 )\r
598{\r
599 CHAR8 Character;\r
600\r
601 for ( ; *String != CHAR_NULL; String++) {\r
602 Character = (CHAR8)*String;\r
603 if (!(TextOutIsValidAscii (Character) || TextOutIsValidEfiCntlChar (Character))) {\r
604 return EFI_UNSUPPORTED;\r
605 }\r
606 }\r
607\r
608 return EFI_SUCCESS;\r
609}\r
610\r
611\r
612EFI_STATUS\r
613EFIAPI\r
614QueryMode (\r
615 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
616 IN UINTN ModeNumber,\r
617 OUT UINTN *Columns,\r
618 OUT UINTN *Rows\r
619 )\r
620{\r
621 if (This->Mode->MaxMode > 1) {\r
622 return EFI_DEVICE_ERROR;\r
623 }\r
624\r
625 if (ModeNumber == 0) {\r
626 *Columns = MODE0_COLUMN_COUNT;\r
627 *Rows = MODE0_ROW_COUNT;\r
628 return EFI_SUCCESS;\r
629 }\r
630\r
631 return EFI_UNSUPPORTED;\r
632}\r
633\r
634\r
635EFI_STATUS\r
636EFIAPI\r
637SetMode (\r
638 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
639 IN UINTN ModeNumber\r
640 )\r
641{\r
642 if (ModeNumber != 0) {\r
643 return EFI_UNSUPPORTED;\r
644 }\r
645\r
646 This->Mode->Mode = 0;\r
647 This->ClearScreen (This);\r
648 return EFI_SUCCESS;\r
649}\r
650\r
651\r
652EFI_STATUS\r
653EFIAPI\r
654SetAttribute(\r
655 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
656 IN UINTN Attribute\r
657 )\r
658{\r
659 This->Mode->Attribute = (INT32)Attribute;\r
660 return EFI_SUCCESS;\r
661}\r
662\r
663\r
664EFI_STATUS\r
665EFIAPI\r
666ClearScreen (\r
667 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
668 )\r
669{\r
670 EFI_STATUS Status;\r
671\r
672 Status = This->SetCursorPosition (This, 0, 0);\r
673 return Status;\r
674}\r
675\r
676\r
677EFI_STATUS\r
678EFIAPI\r
679SetCursorPosition (\r
680 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
681 IN UINTN Column,\r
682 IN UINTN Row\r
683 )\r
684{\r
685 EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;\r
686 EFI_STATUS Status;\r
687 UINTN MaxColumn;\r
688 UINTN MaxRow;\r
689\r
690 Mode = This->Mode;\r
691\r
692 Status = This->QueryMode(\r
693 This,\r
694 Mode->Mode,\r
695 &MaxColumn,\r
696 &MaxRow\r
697 );\r
698 if (EFI_ERROR(Status)) {\r
699 return EFI_UNSUPPORTED;\r
700 }\r
701\r
702 if ((Column >= MaxColumn) || (Row >= MaxRow)) {\r
703 return EFI_UNSUPPORTED;\r
704 }\r
705\r
706 Mode->CursorColumn = (INT32)Column;\r
707 Mode->CursorRow = (INT32)Row;\r
708\r
709 return EFI_SUCCESS;\r
710}\r
711\r
712\r
713EFI_STATUS\r
714EFIAPI\r
715EnableCursor (\r
716 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
717 IN BOOLEAN Enable\r
718 )\r
719{\r
720 if (!Enable) {\r
721 return EFI_UNSUPPORTED;\r
722 }\r
723\r
724 return EFI_SUCCESS;\r
725}\r
726\r
727\r
728EFI_STATUS\r
729EFIAPI\r
730SimpleTextInOutEntryPoint (\r
731 IN EFI_HANDLE ImageHandle,\r
732 IN EFI_SYSTEM_TABLE *SystemTable\r
733 )\r
734{\r
735 EFI_STATUS Status;\r
736\r
737 Status = gBS->CreateEvent (\r
738 EVT_NOTIFY_WAIT,\r
739 TPL_NOTIFY,\r
740 WaitForKeyEvent,\r
741 NULL,\r
742 &mSimpleTextIn.WaitForKey\r
743 );\r
744 ASSERT_EFI_ERROR (Status);\r
745\r
746 Status = gBS->InstallMultipleProtocolInterfaces(\r
747 &mInstallHandle,\r
748 &gEfiSimpleTextInProtocolGuid, &mSimpleTextIn,\r
749 &gEfiSimpleTextOutProtocolGuid, &mSimpleTextOut,\r
750 &gEfiDevicePathProtocolGuid, &mDevicePath,\r
751 NULL\r
752 );\r
753 if (!EFI_ERROR (Status)) {\r
754 gST->ConOut = &mSimpleTextOut;\r
755 gST->ConIn = &mSimpleTextIn;\r
756 }\r
757\r
758 return Status;\r
759}\r