Merge branch '2019-08-11-ti-imports'
[platform/kernel/u-boot.git] / lib / efi_loader / efi_console.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  EFI application console interface
4  *
5  *  Copyright (c) 2016 Alexander Graf
6  */
7
8 #include <common.h>
9 #include <charset.h>
10 #include <dm/device.h>
11 #include <efi_loader.h>
12 #include <env.h>
13 #include <stdio_dev.h>
14 #include <video_console.h>
15
16 #define EFI_COUT_MODE_2 2
17 #define EFI_MAX_COUT_MODE 3
18
19 struct cout_mode {
20         unsigned long columns;
21         unsigned long rows;
22         int present;
23 };
24
25 static struct cout_mode efi_cout_modes[] = {
26         /* EFI Mode 0 is 80x25 and always present */
27         {
28                 .columns = 80,
29                 .rows = 25,
30                 .present = 1,
31         },
32         /* EFI Mode 1 is always 80x50 */
33         {
34                 .columns = 80,
35                 .rows = 50,
36                 .present = 0,
37         },
38         /* Value are unknown until we query the console */
39         {
40                 .columns = 0,
41                 .rows = 0,
42                 .present = 0,
43         },
44 };
45
46 const efi_guid_t efi_guid_text_input_ex_protocol =
47                         EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
48 const efi_guid_t efi_guid_text_input_protocol =
49                         EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
50 const efi_guid_t efi_guid_text_output_protocol =
51                         EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
52
53 #define cESC '\x1b'
54 #define ESC "\x1b"
55
56 /* Default to mode 0 */
57 static struct simple_text_output_mode efi_con_mode = {
58         .max_mode = 1,
59         .mode = 0,
60         .attribute = 0,
61         .cursor_column = 0,
62         .cursor_row = 0,
63         .cursor_visible = 1,
64 };
65
66 static int term_get_char(s32 *c)
67 {
68         u64 timeout;
69
70         /* Wait up to 100 ms for a character */
71         timeout = timer_get_us() + 100000;
72
73         while (!tstc())
74                 if (timer_get_us() > timeout)
75                         return 1;
76
77         *c = getc();
78         return 0;
79 }
80
81 /*
82  * Receive and parse a reply from the terminal.
83  *
84  * @n:          array of return values
85  * @num:        number of return values expected
86  * @end_char:   character indicating end of terminal message
87  * @return:     non-zero indicates error
88  */
89 static int term_read_reply(int *n, int num, char end_char)
90 {
91         s32 c;
92         int i = 0;
93
94         if (term_get_char(&c) || c != cESC)
95                 return -1;
96
97         if (term_get_char(&c) || c != '[')
98                 return -1;
99
100         n[0] = 0;
101         while (1) {
102                 if (!term_get_char(&c)) {
103                         if (c == ';') {
104                                 i++;
105                                 if (i >= num)
106                                         return -1;
107                                 n[i] = 0;
108                                 continue;
109                         } else if (c == end_char) {
110                                 break;
111                         } else if (c > '9' || c < '0') {
112                                 return -1;
113                         }
114
115                         /* Read one more decimal position */
116                         n[i] *= 10;
117                         n[i] += c - '0';
118                 } else {
119                         return -1;
120                 }
121         }
122         if (i != num - 1)
123                 return -1;
124
125         return 0;
126 }
127
128 static efi_status_t EFIAPI efi_cout_output_string(
129                         struct efi_simple_text_output_protocol *this,
130                         const efi_string_t string)
131 {
132         struct simple_text_output_mode *con = &efi_con_mode;
133         struct cout_mode *mode = &efi_cout_modes[con->mode];
134         char *buf, *pos;
135         u16 *p;
136         efi_status_t ret = EFI_SUCCESS;
137
138         EFI_ENTRY("%p, %p", this, string);
139
140         if (!this || !string) {
141                 ret = EFI_INVALID_PARAMETER;
142                 goto out;
143         }
144
145         buf = malloc(utf16_utf8_strlen(string) + 1);
146         if (!buf) {
147                 ret = EFI_OUT_OF_RESOURCES;
148                 goto out;
149         }
150         pos = buf;
151         utf16_utf8_strcpy(&pos, string);
152         fputs(stdout, buf);
153         free(buf);
154
155         /*
156          * Update the cursor position.
157          *
158          * The UEFI spec provides advance rules for U+0000, U+0008, U+000A,
159          * and U000D. All other characters, including control characters
160          * U+0007 (BEL) and U+0009 (TAB), have to increase the column by one.
161          */
162         for (p = string; *p; ++p) {
163                 switch (*p) {
164                 case '\b':      /* U+0008, backspace */
165                         con->cursor_column = max(0, con->cursor_column - 1);
166                         break;
167                 case '\n':      /* U+000A, newline */
168                         con->cursor_column = 0;
169                         con->cursor_row++;
170                         break;
171                 case '\r':      /* U+000D, carriage-return */
172                         con->cursor_column = 0;
173                         break;
174                 case 0xd800 ... 0xdbff:
175                         /*
176                          * Ignore high surrogates, we do not want to count a
177                          * Unicode character twice.
178                          */
179                         break;
180                 default:
181                         con->cursor_column++;
182                         break;
183                 }
184                 if (con->cursor_column >= mode->columns) {
185                         con->cursor_column = 0;
186                         con->cursor_row++;
187                 }
188                 con->cursor_row = min(con->cursor_row, (s32)mode->rows - 1);
189         }
190
191 out:
192         return EFI_EXIT(ret);
193 }
194
195 static efi_status_t EFIAPI efi_cout_test_string(
196                         struct efi_simple_text_output_protocol *this,
197                         const efi_string_t string)
198 {
199         EFI_ENTRY("%p, %p", this, string);
200         return EFI_EXIT(EFI_SUCCESS);
201 }
202
203 static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
204 {
205         if (!mode->present)
206                 return false;
207
208         return (mode->rows == rows) && (mode->columns == cols);
209 }
210
211 /**
212  * query_console_serial() - query console size
213  *
214  * @rows        pointer to return number of rows
215  * @columns     pointer to return number of columns
216  * Returns      0 on success
217  */
218 static int query_console_serial(int *rows, int *cols)
219 {
220         int ret = 0;
221         int n[2];
222
223         /* Empty input buffer */
224         while (tstc())
225                 getc();
226
227         /*
228          * Not all terminals understand CSI [18t for querying the console size.
229          * We should adhere to escape sequences documented in the console_codes
230          * man page and the ECMA-48 standard.
231          *
232          * So here we follow a different approach. We position the cursor to the
233          * bottom right and query its position. Before leaving the function we
234          * restore the original cursor position.
235          */
236         printf(ESC "7"          /* Save cursor position */
237                ESC "[r"         /* Set scrolling region to full window */
238                ESC "[999;999H"  /* Move to bottom right corner */
239                ESC "[6n");      /* Query cursor position */
240
241         /* Read {rows,cols} */
242         if (term_read_reply(n, 2, 'R')) {
243                 ret = 1;
244                 goto out;
245         }
246
247         *cols = n[1];
248         *rows = n[0];
249 out:
250         printf(ESC "8");        /* Restore cursor position */
251         return ret;
252 }
253
254 /*
255  * Update the mode table.
256  *
257  * By default the only mode available is 80x25. If the console has at least 50
258  * lines, enable mode 80x50. If we can query the console size and it is neither
259  * 80x25 nor 80x50, set it as an additional mode.
260  */
261 static void query_console_size(void)
262 {
263         const char *stdout_name = env_get("stdout");
264         int rows = 25, cols = 80;
265
266         if (stdout_name && !strcmp(stdout_name, "vidconsole") &&
267             IS_ENABLED(CONFIG_DM_VIDEO)) {
268                 struct stdio_dev *stdout_dev =
269                         stdio_get_by_name("vidconsole");
270                 struct udevice *dev = stdout_dev->priv;
271                 struct vidconsole_priv *priv =
272                         dev_get_uclass_priv(dev);
273                 rows = priv->rows;
274                 cols = priv->cols;
275         } else if (query_console_serial(&rows, &cols)) {
276                 return;
277         }
278
279         /* Test if we can have Mode 1 */
280         if (cols >= 80 && rows >= 50) {
281                 efi_cout_modes[1].present = 1;
282                 efi_con_mode.max_mode = 2;
283         }
284
285         /*
286          * Install our mode as mode 2 if it is different
287          * than mode 0 or 1 and set it as the currently selected mode
288          */
289         if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
290             !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
291                 efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
292                 efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
293                 efi_cout_modes[EFI_COUT_MODE_2].present = 1;
294                 efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
295                 efi_con_mode.mode = EFI_COUT_MODE_2;
296         }
297 }
298
299 static efi_status_t EFIAPI efi_cout_query_mode(
300                         struct efi_simple_text_output_protocol *this,
301                         unsigned long mode_number, unsigned long *columns,
302                         unsigned long *rows)
303 {
304         EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows);
305
306         if (mode_number >= efi_con_mode.max_mode)
307                 return EFI_EXIT(EFI_UNSUPPORTED);
308
309         if (efi_cout_modes[mode_number].present != 1)
310                 return EFI_EXIT(EFI_UNSUPPORTED);
311
312         if (columns)
313                 *columns = efi_cout_modes[mode_number].columns;
314         if (rows)
315                 *rows = efi_cout_modes[mode_number].rows;
316
317         return EFI_EXIT(EFI_SUCCESS);
318 }
319
320 static const struct {
321         unsigned int fg;
322         unsigned int bg;
323 } color[] = {
324         { 30, 40 },     /* 0: black */
325         { 34, 44 },     /* 1: blue */
326         { 32, 42 },     /* 2: green */
327         { 36, 46 },     /* 3: cyan */
328         { 31, 41 },     /* 4: red */
329         { 35, 45 },     /* 5: magenta */
330         { 33, 43 },     /* 6: brown, map to yellow as EDK2 does*/
331         { 37, 47 },     /* 7: light gray, map to white */
332 };
333
334 /* See EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute(). */
335 static efi_status_t EFIAPI efi_cout_set_attribute(
336                         struct efi_simple_text_output_protocol *this,
337                         unsigned long attribute)
338 {
339         unsigned int bold = EFI_ATTR_BOLD(attribute);
340         unsigned int fg = EFI_ATTR_FG(attribute);
341         unsigned int bg = EFI_ATTR_BG(attribute);
342
343         EFI_ENTRY("%p, %lx", this, attribute);
344
345         efi_con_mode.attribute = attribute;
346         if (attribute)
347                 printf(ESC"[%u;%u;%um", bold, color[fg].fg, color[bg].bg);
348         else
349                 printf(ESC"[0;37;40m");
350
351         return EFI_EXIT(EFI_SUCCESS);
352 }
353
354 static efi_status_t EFIAPI efi_cout_clear_screen(
355                         struct efi_simple_text_output_protocol *this)
356 {
357         EFI_ENTRY("%p", this);
358
359         printf(ESC"[2J");
360         efi_con_mode.cursor_column = 0;
361         efi_con_mode.cursor_row = 0;
362
363         return EFI_EXIT(EFI_SUCCESS);
364 }
365
366 static efi_status_t EFIAPI efi_cout_set_mode(
367                         struct efi_simple_text_output_protocol *this,
368                         unsigned long mode_number)
369 {
370         EFI_ENTRY("%p, %ld", this, mode_number);
371
372         if (mode_number >= efi_con_mode.max_mode)
373                 return EFI_EXIT(EFI_UNSUPPORTED);
374         efi_con_mode.mode = mode_number;
375         EFI_CALL(efi_cout_clear_screen(this));
376
377         return EFI_EXIT(EFI_SUCCESS);
378 }
379
380 static efi_status_t EFIAPI efi_cout_reset(
381                         struct efi_simple_text_output_protocol *this,
382                         char extended_verification)
383 {
384         EFI_ENTRY("%p, %d", this, extended_verification);
385
386         /* Clear screen */
387         EFI_CALL(efi_cout_clear_screen(this));
388         /* Set default colors */
389         efi_con_mode.attribute = 0x07;
390         printf(ESC "[0;37;40m");
391
392         return EFI_EXIT(EFI_SUCCESS);
393 }
394
395 static efi_status_t EFIAPI efi_cout_set_cursor_position(
396                         struct efi_simple_text_output_protocol *this,
397                         unsigned long column, unsigned long row)
398 {
399         efi_status_t ret = EFI_SUCCESS;
400         struct simple_text_output_mode *con = &efi_con_mode;
401         struct cout_mode *mode = &efi_cout_modes[con->mode];
402
403         EFI_ENTRY("%p, %ld, %ld", this, column, row);
404
405         /* Check parameters */
406         if (!this) {
407                 ret = EFI_INVALID_PARAMETER;
408                 goto out;
409         }
410         if (row >= mode->rows || column >= mode->columns) {
411                 ret = EFI_UNSUPPORTED;
412                 goto out;
413         }
414
415         /*
416          * Set cursor position by sending CSI H.
417          * EFI origin is [0, 0], terminal origin is [1, 1].
418          */
419         printf(ESC "[%d;%dH", (int)row + 1, (int)column + 1);
420         efi_con_mode.cursor_column = column;
421         efi_con_mode.cursor_row = row;
422 out:
423         return EFI_EXIT(ret);
424 }
425
426 static efi_status_t EFIAPI efi_cout_enable_cursor(
427                         struct efi_simple_text_output_protocol *this,
428                         bool enable)
429 {
430         EFI_ENTRY("%p, %d", this, enable);
431
432         printf(ESC"[?25%c", enable ? 'h' : 'l');
433         efi_con_mode.cursor_visible = !!enable;
434
435         return EFI_EXIT(EFI_SUCCESS);
436 }
437
438 struct efi_simple_text_output_protocol efi_con_out = {
439         .reset = efi_cout_reset,
440         .output_string = efi_cout_output_string,
441         .test_string = efi_cout_test_string,
442         .query_mode = efi_cout_query_mode,
443         .set_mode = efi_cout_set_mode,
444         .set_attribute = efi_cout_set_attribute,
445         .clear_screen = efi_cout_clear_screen,
446         .set_cursor_position = efi_cout_set_cursor_position,
447         .enable_cursor = efi_cout_enable_cursor,
448         .mode = (void*)&efi_con_mode,
449 };
450
451 /**
452  * struct efi_cin_notify_function - registered console input notify function
453  *
454  * @link:       link to list
455  * @data:       key to notify
456  * @function:   function to call
457  */
458 struct efi_cin_notify_function {
459         struct list_head link;
460         struct efi_key_data key;
461         efi_status_t (EFIAPI *function)
462                 (struct efi_key_data *key_data);
463 };
464
465 static bool key_available;
466 static struct efi_key_data next_key;
467 static LIST_HEAD(cin_notify_functions);
468
469 /**
470  * set_shift_mask() - set shift mask
471  *
472  * @mod:        Xterm shift mask
473  */
474 void set_shift_mask(int mod, struct efi_key_state *key_state)
475 {
476         key_state->key_shift_state = EFI_SHIFT_STATE_VALID;
477         if (mod) {
478                 --mod;
479                 if (mod & 1)
480                         key_state->key_shift_state |= EFI_LEFT_SHIFT_PRESSED;
481                 if (mod & 2)
482                         key_state->key_shift_state |= EFI_LEFT_ALT_PRESSED;
483                 if (mod & 4)
484                         key_state->key_shift_state |= EFI_LEFT_CONTROL_PRESSED;
485                 if (!mod || (mod & 8))
486                         key_state->key_shift_state |= EFI_LEFT_LOGO_PRESSED;
487         }
488 }
489
490 /**
491  * analyze_modifiers() - analyze modifiers (shift, alt, ctrl) for function keys
492  *
493  * This gets called when we have already parsed CSI.
494  *
495  * @modifiers:  bit mask (shift, alt, ctrl)
496  * @return:     the unmodified code
497  */
498 static int analyze_modifiers(struct efi_key_state *key_state)
499 {
500         int c, mod = 0, ret = 0;
501
502         c = getc();
503
504         if (c != ';') {
505                 ret = c;
506                 if (c == '~')
507                         goto out;
508                 c = getc();
509         }
510         for (;;) {
511                 switch (c) {
512                 case '0'...'9':
513                         mod *= 10;
514                         mod += c - '0';
515                 /* fall through */
516                 case ';':
517                         c = getc();
518                         break;
519                 default:
520                         goto out;
521                 }
522         }
523 out:
524         set_shift_mask(mod, key_state);
525         if (!ret)
526                 ret = c;
527         return ret;
528 }
529
530 /**
531  * efi_cin_read_key() - read a key from the console input
532  *
533  * @key:        - key received
534  * Return:      - status code
535  */
536 static efi_status_t efi_cin_read_key(struct efi_key_data *key)
537 {
538         struct efi_input_key pressed_key = {
539                 .scan_code = 0,
540                 .unicode_char = 0,
541         };
542         s32 ch;
543
544         if (console_read_unicode(&ch))
545                 return EFI_NOT_READY;
546
547         key->key_state.key_shift_state = EFI_SHIFT_STATE_INVALID;
548         key->key_state.key_toggle_state = EFI_TOGGLE_STATE_INVALID;
549
550         /* We do not support multi-word codes */
551         if (ch >= 0x10000)
552                 ch = '?';
553
554         switch (ch) {
555         case 0x1b:
556                 /*
557                  * Xterm Control Sequences
558                  * https://www.xfree86.org/4.8.0/ctlseqs.html
559                  */
560                 ch = getc();
561                 switch (ch) {
562                 case cESC: /* ESC */
563                         pressed_key.scan_code = 23;
564                         break;
565                 case 'O': /* F1 - F4, End */
566                         ch = getc();
567                         /* consider modifiers */
568                         if (ch == 'F') { /* End */
569                                 pressed_key.scan_code = 6;
570                                 break;
571                         } else if (ch < 'P') {
572                                 set_shift_mask(ch - '0', &key->key_state);
573                                 ch = getc();
574                         }
575                         pressed_key.scan_code = ch - 'P' + 11;
576                         break;
577                 case '[':
578                         ch = getc();
579                         switch (ch) {
580                         case 'A'...'D': /* up, down right, left */
581                                 pressed_key.scan_code = ch - 'A' + 1;
582                                 break;
583                         case 'F': /* End */
584                                 pressed_key.scan_code = 6;
585                                 break;
586                         case 'H': /* Home */
587                                 pressed_key.scan_code = 5;
588                                 break;
589                         case '1':
590                                 ch = analyze_modifiers(&key->key_state);
591                                 switch (ch) {
592                                 case '1'...'5': /* F1 - F5 */
593                                         pressed_key.scan_code = ch - '1' + 11;
594                                         break;
595                                 case '6'...'9': /* F5 - F8 */
596                                         pressed_key.scan_code = ch - '6' + 15;
597                                         break;
598                                 case 'A'...'D': /* up, down right, left */
599                                         pressed_key.scan_code = ch - 'A' + 1;
600                                         break;
601                                 case 'F': /* End */
602                                         pressed_key.scan_code = 6;
603                                         break;
604                                 case 'H': /* Home */
605                                         pressed_key.scan_code = 5;
606                                         break;
607                                 case '~': /* Home */
608                                         pressed_key.scan_code = 5;
609                                         break;
610                                 }
611                                 break;
612                         case '2':
613                                 ch = analyze_modifiers(&key->key_state);
614                                 switch (ch) {
615                                 case '0'...'1': /* F9 - F10 */
616                                         pressed_key.scan_code = ch - '0' + 19;
617                                         break;
618                                 case '3'...'4': /* F11 - F12 */
619                                         pressed_key.scan_code = ch - '3' + 21;
620                                         break;
621                                 case '~': /* INS */
622                                         pressed_key.scan_code = 7;
623                                         break;
624                                 }
625                                 break;
626                         case '3': /* DEL */
627                                 pressed_key.scan_code = 8;
628                                 analyze_modifiers(&key->key_state);
629                                 break;
630                         case '5': /* PG UP */
631                                 pressed_key.scan_code = 9;
632                                 analyze_modifiers(&key->key_state);
633                                 break;
634                         case '6': /* PG DOWN */
635                                 pressed_key.scan_code = 10;
636                                 analyze_modifiers(&key->key_state);
637                                 break;
638                         } /* [ */
639                         break;
640                 default:
641                         /* ALT key */
642                         set_shift_mask(3, &key->key_state);
643                 }
644                 break;
645         case 0x7f:
646                 /* Backspace */
647                 ch = 0x08;
648         }
649         if (pressed_key.scan_code) {
650                 key->key_state.key_shift_state |= EFI_SHIFT_STATE_VALID;
651         } else {
652                 pressed_key.unicode_char = ch;
653
654                 /*
655                  * Assume left control key for control characters typically
656                  * entered using the control key.
657                  */
658                 if (ch >= 0x01 && ch <= 0x1f) {
659                         key->key_state.key_shift_state |=
660                                         EFI_SHIFT_STATE_VALID;
661                         switch (ch) {
662                         case 0x01 ... 0x07:
663                         case 0x0b ... 0x0c:
664                         case 0x0e ... 0x1f:
665                                 key->key_state.key_shift_state |=
666                                                 EFI_LEFT_CONTROL_PRESSED;
667                         }
668                 }
669         }
670         key->key = pressed_key;
671
672         return EFI_SUCCESS;
673 }
674
675 /**
676  * efi_cin_notify() - notify registered functions
677  */
678 static void efi_cin_notify(void)
679 {
680         struct efi_cin_notify_function *item;
681
682         list_for_each_entry(item, &cin_notify_functions, link) {
683                 bool match = true;
684
685                 /* We do not support toggle states */
686                 if (item->key.key.unicode_char || item->key.key.scan_code) {
687                         if (item->key.key.unicode_char !=
688                             next_key.key.unicode_char ||
689                             item->key.key.scan_code != next_key.key.scan_code)
690                                 match = false;
691                 }
692                 if (item->key.key_state.key_shift_state &&
693                     item->key.key_state.key_shift_state !=
694                     next_key.key_state.key_shift_state)
695                         match = false;
696
697                 if (match)
698                         /* We don't bother about the return code */
699                         EFI_CALL(item->function(&next_key));
700         }
701 }
702
703 /**
704  * efi_cin_check() - check if keyboard input is available
705  */
706 static void efi_cin_check(void)
707 {
708         efi_status_t ret;
709
710         if (key_available) {
711                 efi_signal_event(efi_con_in.wait_for_key);
712                 return;
713         }
714
715         if (tstc()) {
716                 ret = efi_cin_read_key(&next_key);
717                 if (ret == EFI_SUCCESS) {
718                         key_available = true;
719
720                         /* Notify registered functions */
721                         efi_cin_notify();
722
723                         /* Queue the wait for key event */
724                         if (key_available)
725                                 efi_signal_event(efi_con_in.wait_for_key);
726                 }
727         }
728 }
729
730 /**
731  * efi_cin_empty_buffer() - empty input buffer
732  */
733 static void efi_cin_empty_buffer(void)
734 {
735         while (tstc())
736                 getc();
737         key_available = false;
738 }
739
740 /**
741  * efi_cin_reset_ex() - reset console input
742  *
743  * @this:                       - the extended simple text input protocol
744  * @extended_verification:      - extended verification
745  *
746  * This function implements the reset service of the
747  * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
748  *
749  * See the Unified Extensible Firmware Interface (UEFI) specification for
750  * details.
751  *
752  * Return: old value of the task priority level
753  */
754 static efi_status_t EFIAPI efi_cin_reset_ex(
755                 struct efi_simple_text_input_ex_protocol *this,
756                 bool extended_verification)
757 {
758         efi_status_t ret = EFI_SUCCESS;
759
760         EFI_ENTRY("%p, %d", this, extended_verification);
761
762         /* Check parameters */
763         if (!this) {
764                 ret = EFI_INVALID_PARAMETER;
765                 goto out;
766         }
767
768         efi_cin_empty_buffer();
769 out:
770         return EFI_EXIT(ret);
771 }
772
773 /**
774  * efi_cin_read_key_stroke_ex() - read key stroke
775  *
776  * @this:       instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
777  * @key_data:   key read from console
778  * Return:      status code
779  *
780  * This function implements the ReadKeyStrokeEx service of the
781  * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
782  *
783  * See the Unified Extensible Firmware Interface (UEFI) specification for
784  * details.
785  */
786 static efi_status_t EFIAPI efi_cin_read_key_stroke_ex(
787                 struct efi_simple_text_input_ex_protocol *this,
788                 struct efi_key_data *key_data)
789 {
790         efi_status_t ret = EFI_SUCCESS;
791
792         EFI_ENTRY("%p, %p", this, key_data);
793
794         /* Check parameters */
795         if (!this || !key_data) {
796                 ret = EFI_INVALID_PARAMETER;
797                 goto out;
798         }
799
800         /* We don't do interrupts, so check for timers cooperatively */
801         efi_timer_check();
802
803         /* Enable console input after ExitBootServices */
804         efi_cin_check();
805
806         if (!key_available) {
807                 ret = EFI_NOT_READY;
808                 goto out;
809         }
810         /*
811          * CTRL+A - CTRL+Z have to be signaled as a - z.
812          * SHIFT+CTRL+A - SHIFT+CTRL+Z have to be signaled as A - Z.
813          */
814         switch (next_key.key.unicode_char) {
815         case 0x01 ... 0x07:
816         case 0x0b ... 0x0c:
817         case 0x0e ... 0x1a:
818                 if (!(next_key.key_state.key_toggle_state &
819                       EFI_CAPS_LOCK_ACTIVE) ^
820                     !(next_key.key_state.key_shift_state &
821                       (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)))
822                         next_key.key.unicode_char += 0x40;
823                 else
824                         next_key.key.unicode_char += 0x60;
825         }
826         *key_data = next_key;
827         key_available = false;
828         efi_con_in.wait_for_key->is_signaled = false;
829
830 out:
831         return EFI_EXIT(ret);
832 }
833
834 /**
835  * efi_cin_set_state() - set toggle key state
836  *
837  * @this:               instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
838  * @key_toggle_state:   pointer to key toggle state
839  * Return:              status code
840  *
841  * This function implements the SetState service of the
842  * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
843  *
844  * See the Unified Extensible Firmware Interface (UEFI) specification for
845  * details.
846  */
847 static efi_status_t EFIAPI efi_cin_set_state(
848                 struct efi_simple_text_input_ex_protocol *this,
849                 u8 *key_toggle_state)
850 {
851         EFI_ENTRY("%p, %p", this, key_toggle_state);
852         /*
853          * U-Boot supports multiple console input sources like serial and
854          * net console for which a key toggle state cannot be set at all.
855          *
856          * According to the UEFI specification it is allowable to not implement
857          * this service.
858          */
859         return EFI_EXIT(EFI_UNSUPPORTED);
860 }
861
862 /**
863  * efi_cin_register_key_notify() - register key notification function
864  *
865  * @this:                       instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
866  * @key_data:                   key to be notified
867  * @key_notify_function:        function to be called if the key is pressed
868  * @notify_handle:              handle for unregistering the notification
869  * Return:                      status code
870  *
871  * This function implements the SetState service of the
872  * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
873  *
874  * See the Unified Extensible Firmware Interface (UEFI) specification for
875  * details.
876  */
877 static efi_status_t EFIAPI efi_cin_register_key_notify(
878                 struct efi_simple_text_input_ex_protocol *this,
879                 struct efi_key_data *key_data,
880                 efi_status_t (EFIAPI *key_notify_function)(
881                         struct efi_key_data *key_data),
882                 void **notify_handle)
883 {
884         efi_status_t ret = EFI_SUCCESS;
885         struct efi_cin_notify_function *notify_function;
886
887         EFI_ENTRY("%p, %p, %p, %p",
888                   this, key_data, key_notify_function, notify_handle);
889
890         /* Check parameters */
891         if (!this || !key_data || !key_notify_function || !notify_handle) {
892                 ret = EFI_INVALID_PARAMETER;
893                 goto out;
894         }
895
896         EFI_PRINT("u+%04x, sc %04x, sh %08x, tg %02x\n",
897                   key_data->key.unicode_char,
898                key_data->key.scan_code,
899                key_data->key_state.key_shift_state,
900                key_data->key_state.key_toggle_state);
901
902         notify_function = calloc(1, sizeof(struct efi_cin_notify_function));
903         if (!notify_function) {
904                 ret = EFI_OUT_OF_RESOURCES;
905                 goto out;
906         }
907         notify_function->key = *key_data;
908         notify_function->function = key_notify_function;
909         list_add_tail(&notify_function->link, &cin_notify_functions);
910         *notify_handle = notify_function;
911 out:
912         return EFI_EXIT(ret);
913 }
914
915 /**
916  * efi_cin_unregister_key_notify() - unregister key notification function
917  *
918  * @this:                       instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
919  * @notification_handle:        handle received when registering
920  * Return:                      status code
921  *
922  * This function implements the SetState service of the
923  * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
924  *
925  * See the Unified Extensible Firmware Interface (UEFI) specification for
926  * details.
927  */
928 static efi_status_t EFIAPI efi_cin_unregister_key_notify(
929                 struct efi_simple_text_input_ex_protocol *this,
930                 void *notification_handle)
931 {
932         efi_status_t ret = EFI_INVALID_PARAMETER;
933         struct efi_cin_notify_function *item, *notify_function =
934                         notification_handle;
935
936         EFI_ENTRY("%p, %p", this, notification_handle);
937
938         /* Check parameters */
939         if (!this || !notification_handle)
940                 goto out;
941
942         list_for_each_entry(item, &cin_notify_functions, link) {
943                 if (item == notify_function) {
944                         ret = EFI_SUCCESS;
945                         break;
946                 }
947         }
948         if (ret != EFI_SUCCESS)
949                 goto out;
950
951         /* Remove the notify function */
952         list_del(&notify_function->link);
953         free(notify_function);
954 out:
955         return EFI_EXIT(ret);
956 }
957
958
959 /**
960  * efi_cin_reset() - drain the input buffer
961  *
962  * @this:                       instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
963  * @extended_verification:      allow for exhaustive verification
964  * Return:                      status code
965  *
966  * This function implements the Reset service of the
967  * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
968  *
969  * See the Unified Extensible Firmware Interface (UEFI) specification for
970  * details.
971  */
972 static efi_status_t EFIAPI efi_cin_reset
973                         (struct efi_simple_text_input_protocol *this,
974                          bool extended_verification)
975 {
976         efi_status_t ret = EFI_SUCCESS;
977
978         EFI_ENTRY("%p, %d", this, extended_verification);
979
980         /* Check parameters */
981         if (!this) {
982                 ret = EFI_INVALID_PARAMETER;
983                 goto out;
984         }
985
986         efi_cin_empty_buffer();
987 out:
988         return EFI_EXIT(ret);
989 }
990
991 /**
992  * efi_cin_read_key_stroke() - read key stroke
993  *
994  * @this:       instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
995  * @key:        key read from console
996  * Return:      status code
997  *
998  * This function implements the ReadKeyStroke service of the
999  * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
1000  *
1001  * See the Unified Extensible Firmware Interface (UEFI) specification for
1002  * details.
1003  */
1004 static efi_status_t EFIAPI efi_cin_read_key_stroke
1005                         (struct efi_simple_text_input_protocol *this,
1006                          struct efi_input_key *key)
1007 {
1008         efi_status_t ret = EFI_SUCCESS;
1009
1010         EFI_ENTRY("%p, %p", this, key);
1011
1012         /* Check parameters */
1013         if (!this || !key) {
1014                 ret = EFI_INVALID_PARAMETER;
1015                 goto out;
1016         }
1017
1018         /* We don't do interrupts, so check for timers cooperatively */
1019         efi_timer_check();
1020
1021         /* Enable console input after ExitBootServices */
1022         efi_cin_check();
1023
1024         if (!key_available) {
1025                 ret = EFI_NOT_READY;
1026                 goto out;
1027         }
1028         *key = next_key.key;
1029         key_available = false;
1030         efi_con_in.wait_for_key->is_signaled = false;
1031 out:
1032         return EFI_EXIT(ret);
1033 }
1034
1035 static struct efi_simple_text_input_ex_protocol efi_con_in_ex = {
1036         .reset = efi_cin_reset_ex,
1037         .read_key_stroke_ex = efi_cin_read_key_stroke_ex,
1038         .wait_for_key_ex = NULL,
1039         .set_state = efi_cin_set_state,
1040         .register_key_notify = efi_cin_register_key_notify,
1041         .unregister_key_notify = efi_cin_unregister_key_notify,
1042 };
1043
1044 struct efi_simple_text_input_protocol efi_con_in = {
1045         .reset = efi_cin_reset,
1046         .read_key_stroke = efi_cin_read_key_stroke,
1047         .wait_for_key = NULL,
1048 };
1049
1050 static struct efi_event *console_timer_event;
1051
1052 /*
1053  * efi_console_timer_notify() - notify the console timer event
1054  *
1055  * @event:      console timer event
1056  * @context:    not used
1057  */
1058 static void EFIAPI efi_console_timer_notify(struct efi_event *event,
1059                                             void *context)
1060 {
1061         EFI_ENTRY("%p, %p", event, context);
1062         efi_cin_check();
1063         EFI_EXIT(EFI_SUCCESS);
1064 }
1065
1066 /**
1067  * efi_key_notify() - notify the wait for key event
1068  *
1069  * @event:      wait for key event
1070  * @context:    not used
1071  */
1072 static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
1073 {
1074         EFI_ENTRY("%p, %p", event, context);
1075         efi_cin_check();
1076         EFI_EXIT(EFI_SUCCESS);
1077 }
1078
1079 /**
1080  * efi_console_register() - install the console protocols
1081  *
1082  * This function is called from do_bootefi_exec().
1083  *
1084  * Return:      status code
1085  */
1086 efi_status_t efi_console_register(void)
1087 {
1088         efi_status_t r;
1089         efi_handle_t console_output_handle;
1090         efi_handle_t console_input_handle;
1091
1092         /* Set up mode information */
1093         query_console_size();
1094
1095         /* Create handles */
1096         r = efi_create_handle(&console_output_handle);
1097         if (r != EFI_SUCCESS)
1098                 goto out_of_memory;
1099
1100         r = efi_add_protocol(console_output_handle,
1101                              &efi_guid_text_output_protocol, &efi_con_out);
1102         if (r != EFI_SUCCESS)
1103                 goto out_of_memory;
1104         systab.con_out_handle = console_output_handle;
1105         systab.stderr_handle = console_output_handle;
1106
1107         r = efi_create_handle(&console_input_handle);
1108         if (r != EFI_SUCCESS)
1109                 goto out_of_memory;
1110
1111         r = efi_add_protocol(console_input_handle,
1112                              &efi_guid_text_input_protocol, &efi_con_in);
1113         if (r != EFI_SUCCESS)
1114                 goto out_of_memory;
1115         systab.con_in_handle = console_input_handle;
1116         r = efi_add_protocol(console_input_handle,
1117                              &efi_guid_text_input_ex_protocol, &efi_con_in_ex);
1118         if (r != EFI_SUCCESS)
1119                 goto out_of_memory;
1120
1121         /* Create console events */
1122         r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
1123                              NULL, NULL, &efi_con_in.wait_for_key);
1124         if (r != EFI_SUCCESS) {
1125                 printf("ERROR: Failed to register WaitForKey event\n");
1126                 return r;
1127         }
1128         efi_con_in_ex.wait_for_key_ex = efi_con_in.wait_for_key;
1129         r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
1130                              efi_console_timer_notify, NULL, NULL,
1131                              &console_timer_event);
1132         if (r != EFI_SUCCESS) {
1133                 printf("ERROR: Failed to register console event\n");
1134                 return r;
1135         }
1136         /* 5000 ns cycle is sufficient for 2 MBaud */
1137         r = efi_set_timer(console_timer_event, EFI_TIMER_PERIODIC, 50);
1138         if (r != EFI_SUCCESS)
1139                 printf("ERROR: Failed to set console timer\n");
1140         return r;
1141 out_of_memory:
1142         printf("ERROR: Out of memory\n");
1143         return r;
1144 }