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