1 // SPDX-License-Identifier: GPL-2.0+
3 * EFI application console interface
5 * Copyright (c) 2016 Alexander Graf
8 #define LOG_CATEGORY LOGC_EFI
14 #include <dm/device.h>
15 #include <efi_loader.h>
18 #include <stdio_dev.h>
19 #include <video_console.h>
20 #include <linux/delay.h>
22 #define EFI_COUT_MODE_2 2
23 #define EFI_MAX_COUT_MODE 3
26 unsigned long columns;
31 __maybe_unused static struct efi_object uart_obj;
33 static struct cout_mode efi_cout_modes[] = {
34 /* EFI Mode 0 is 80x25 and always present */
40 /* EFI Mode 1 is always 80x50 */
46 /* Value are unknown until we query the console */
54 const efi_guid_t efi_guid_text_input_ex_protocol =
55 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
56 const efi_guid_t efi_guid_text_input_protocol =
57 EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
58 const efi_guid_t efi_guid_text_output_protocol =
59 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
65 * efi_con_mode - mode information of the Simple Text Output Protocol
67 * Use safe settings before efi_setup_console_size() is called.
68 * By default enable only the 80x25 mode which must always exist.
70 static struct simple_text_output_mode efi_con_mode = {
80 * term_get_char() - read a character from the console
82 * Wait for up to 100 ms to read a character from the console.
84 * @c: pointer to the buffer to receive the character
85 * Return: 0 on success, 1 otherwise
87 static int term_get_char(s32 *c)
91 /* Wait up to 100 ms for a character */
92 timeout = timer_get_us() + 100000;
95 if (timer_get_us() > timeout)
103 * term_read_reply() - receive and parse a reply from the terminal
105 * @n: array of return values
106 * @num: number of return values expected
107 * @end_char: character indicating end of terminal message
108 * Return: non-zero indicates error
110 static int term_read_reply(int *n, int num, char end_char)
115 if (term_get_char(&c) || c != cESC)
118 if (term_get_char(&c) || c != '[')
123 if (!term_get_char(&c)) {
130 } else if (c == end_char) {
132 } else if (c > '9' || c < '0') {
136 /* Read one more decimal position */
150 * efi_cout_output_string() - write Unicode string to console
152 * This function implements the OutputString service of the simple text output
153 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
156 * @this: simple text output protocol
157 * @string: u16 string
158 * Return: status code
160 static efi_status_t EFIAPI efi_cout_output_string(
161 struct efi_simple_text_output_protocol *this,
164 struct simple_text_output_mode *con = &efi_con_mode;
165 struct cout_mode *mode = &efi_cout_modes[con->mode];
168 efi_status_t ret = EFI_SUCCESS;
170 EFI_ENTRY("%p, %p", this, string);
172 if (!this || !string) {
173 ret = EFI_INVALID_PARAMETER;
177 buf = malloc(utf16_utf8_strlen(string) + 1);
179 ret = EFI_OUT_OF_RESOURCES;
183 utf16_utf8_strcpy(&pos, string);
188 * Update the cursor position.
190 * The UEFI spec provides advance rules for U+0000, U+0008, U+000A,
191 * and U000D. All other control characters are ignored. Any non-control
192 * character increase the column by one.
194 for (p = string; *p; ++p) {
196 case '\b': /* U+0008, backspace */
197 if (con->cursor_column)
198 con->cursor_column--;
200 case '\n': /* U+000A, newline */
201 con->cursor_column = 0;
204 case '\r': /* U+000D, carriage-return */
205 con->cursor_column = 0;
207 case 0xd800 ... 0xdbff:
209 * Ignore high surrogates, we do not want to count a
210 * Unicode character twice.
214 /* Exclude control codes */
216 con->cursor_column++;
219 if (con->cursor_column >= mode->columns) {
220 con->cursor_column = 0;
224 * When we exceed the row count the terminal will scroll up one
225 * line. We have to adjust the cursor position.
227 if (con->cursor_row >= mode->rows && con->cursor_row)
232 return EFI_EXIT(ret);
236 * efi_cout_test_string() - test writing Unicode string to console
238 * This function implements the TestString service of the simple text output
239 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
242 * As in OutputString we simply convert UTF-16 to UTF-8 there are no unsupported
243 * code points and we can always return EFI_SUCCESS.
245 * @this: simple text output protocol
246 * @string: u16 string
247 * Return: status code
249 static efi_status_t EFIAPI efi_cout_test_string(
250 struct efi_simple_text_output_protocol *this,
253 EFI_ENTRY("%p, %p", this, string);
254 return EFI_EXIT(EFI_SUCCESS);
258 * cout_mode_matches() - check if mode has given terminal size
261 * @rows: number of rows
262 * @cols: number of columns
263 * Return: true if number of rows and columns matches the mode and
264 * the mode is present
266 static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
271 return (mode->rows == rows) && (mode->columns == cols);
275 * query_console_serial() - query serial console size
277 * When using a serial console or the net console we can only devise the
278 * terminal size by querying the terminal using ECMA-48 control sequences.
280 * @rows: pointer to return number of rows
281 * @cols: pointer to return number of columns
282 * Returns: 0 on success
284 static int query_console_serial(int *rows, int *cols)
289 /* Empty input buffer */
294 * Not all terminals understand CSI [18t for querying the console size.
295 * We should adhere to escape sequences documented in the console_codes
296 * man page and the ECMA-48 standard.
298 * So here we follow a different approach. We position the cursor to the
299 * bottom right and query its position. Before leaving the function we
300 * restore the original cursor position.
302 printf(ESC "7" /* Save cursor position */
303 ESC "[r" /* Set scrolling region to full window */
304 ESC "[999;999H" /* Move to bottom right corner */
305 ESC "[6n"); /* Query cursor position */
307 /* Read {rows,cols} */
308 if (term_read_reply(n, 2, 'R')) {
316 printf(ESC "8"); /* Restore cursor position */
321 * query_vidconsole() - query video console size
324 * @rows: pointer to return number of rows
325 * @cols: pointer to return number of columns
326 * Returns: 0 on success
328 static int __maybe_unused query_vidconsole(int *rows, int *cols)
330 const char *stdout_name = env_get("stdout");
331 struct stdio_dev *stdout_dev;
333 struct vidconsole_priv *priv;
335 if (!stdout_name || strncmp(stdout_name, "vidconsole", 10))
337 stdout_dev = stdio_get_by_name("vidconsole");
340 dev = stdout_dev->priv;
343 priv = dev_get_uclass_priv(dev);
352 * efi_setup_console_size() - update the mode table.
354 * By default the only mode available is 80x25. If the console has at least 50
355 * lines, enable mode 80x50. If we can query the console size and it is neither
356 * 80x25 nor 80x50, set it as an additional mode.
358 void efi_setup_console_size(void)
360 int rows = 25, cols = 80;
363 if (IS_ENABLED(CONFIG_VIDEO))
364 ret = query_vidconsole(&rows, &cols);
366 ret = query_console_serial(&rows, &cols);
370 log_debug("Console size %dx%d\n", rows, cols);
372 /* Test if we can have Mode 1 */
373 if (cols >= 80 && rows >= 50) {
374 efi_cout_modes[1].present = 1;
375 efi_con_mode.max_mode = 2;
379 * Install our mode as mode 2 if it is different
380 * than mode 0 or 1 and set it as the currently selected mode
382 if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
383 !cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
384 efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
385 efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
386 efi_cout_modes[EFI_COUT_MODE_2].present = 1;
387 efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
388 efi_con_mode.mode = EFI_COUT_MODE_2;
393 * efi_cout_query_mode() - get terminal size for a text mode
395 * This function implements the QueryMode service of the simple text output
396 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
399 * @this: simple text output protocol
400 * @mode_number: mode number to retrieve information on
401 * @columns: number of columns
402 * @rows: number of rows
403 * Return: status code
405 static efi_status_t EFIAPI efi_cout_query_mode(
406 struct efi_simple_text_output_protocol *this,
407 unsigned long mode_number, unsigned long *columns,
410 EFI_ENTRY("%p, %ld, %p, %p", this, mode_number, columns, rows);
412 if (mode_number >= efi_con_mode.max_mode)
413 return EFI_EXIT(EFI_UNSUPPORTED);
415 if (efi_cout_modes[mode_number].present != 1)
416 return EFI_EXIT(EFI_UNSUPPORTED);
419 *columns = efi_cout_modes[mode_number].columns;
421 *rows = efi_cout_modes[mode_number].rows;
423 return EFI_EXIT(EFI_SUCCESS);
426 static const struct {
430 { 30, 40 }, /* 0: black */
431 { 34, 44 }, /* 1: blue */
432 { 32, 42 }, /* 2: green */
433 { 36, 46 }, /* 3: cyan */
434 { 31, 41 }, /* 4: red */
435 { 35, 45 }, /* 5: magenta */
436 { 33, 43 }, /* 6: brown, map to yellow as EDK2 does*/
437 { 37, 47 }, /* 7: light gray, map to white */
441 * efi_cout_set_attribute() - set fore- and background color
443 * This function implements the SetAttribute service of the simple text output
444 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
447 * @this: simple text output protocol
448 * @attribute: foreground color - bits 0-3, background color - bits 4-6
449 * Return: status code
451 static efi_status_t EFIAPI efi_cout_set_attribute(
452 struct efi_simple_text_output_protocol *this,
453 unsigned long attribute)
455 unsigned int bold = EFI_ATTR_BOLD(attribute);
456 unsigned int fg = EFI_ATTR_FG(attribute);
457 unsigned int bg = EFI_ATTR_BG(attribute);
459 EFI_ENTRY("%p, %lx", this, attribute);
461 efi_con_mode.attribute = attribute;
463 printf(ESC"[%u;%u;%um", bold, color[fg].fg, color[bg].bg);
465 printf(ESC"[0;37;40m");
467 return EFI_EXIT(EFI_SUCCESS);
471 * efi_clear_screen() - clear screen
473 static void efi_clear_screen(void)
475 if (CONFIG_IS_ENABLED(EFI_SCROLL_ON_CLEAR_SCREEN)) {
476 unsigned int row, screen_rows, screen_columns;
478 /* Avoid overwriting previous outputs on streaming consoles */
479 screen_rows = efi_cout_modes[efi_con_mode.mode].rows;
480 screen_columns = efi_cout_modes[efi_con_mode.mode].columns;
481 printf(ESC "[%u;%uH", screen_rows, screen_columns);
482 for (row = 1; row < screen_rows; row++)
487 * The Linux console wants both a clear and a home command. The video
488 * uclass does not support <ESC>[H without coordinates, yet.
490 printf(ESC "[2J" ESC "[1;1H");
491 efi_con_mode.cursor_column = 0;
492 efi_con_mode.cursor_row = 0;
496 * efi_cout_clear_screen() - clear screen
498 * This function implements the ClearScreen service of the simple text output
499 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
502 * @this: pointer to the protocol instance
503 * Return: status code
505 static efi_status_t EFIAPI efi_cout_clear_screen(
506 struct efi_simple_text_output_protocol *this)
508 EFI_ENTRY("%p", this);
510 /* Set default colors if not done yet */
511 if (efi_con_mode.attribute == 0) {
512 efi_con_mode.attribute = 0x07;
513 printf(ESC "[0;37;40m");
518 return EFI_EXIT(EFI_SUCCESS);
522 * efi_cout_clear_set_mode() - set text model
524 * This function implements the SetMode service of the simple text output
525 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
528 * @this: pointer to the protocol instance
529 * @mode_number: number of the text mode to set
530 * Return: status code
532 static efi_status_t EFIAPI efi_cout_set_mode(
533 struct efi_simple_text_output_protocol *this,
534 unsigned long mode_number)
536 EFI_ENTRY("%p, %ld", this, mode_number);
538 if (mode_number >= efi_con_mode.max_mode)
539 return EFI_EXIT(EFI_UNSUPPORTED);
541 if (!efi_cout_modes[mode_number].present)
542 return EFI_EXIT(EFI_UNSUPPORTED);
544 efi_con_mode.mode = mode_number;
547 return EFI_EXIT(EFI_SUCCESS);
551 * efi_cout_reset() - reset the terminal
553 * This function implements the Reset service of the simple text output
554 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
557 * @this: pointer to the protocol instance
558 * @extended_verification: if set an extended verification may be executed
559 * Return: status code
561 static efi_status_t EFIAPI efi_cout_reset(
562 struct efi_simple_text_output_protocol *this,
563 char extended_verification)
565 EFI_ENTRY("%p, %d", this, extended_verification);
567 /* Set default colors */
568 efi_con_mode.attribute = 0x07;
569 printf(ESC "[0;37;40m");
573 return EFI_EXIT(EFI_SUCCESS);
577 * efi_cout_set_cursor_position() - reset the terminal
579 * This function implements the SetCursorPosition service of the simple text
580 * output protocol. See the Unified Extensible Firmware Interface (UEFI)
581 * specification for details.
583 * @this: pointer to the protocol instance
584 * @column: column to move to
585 * @row: row to move to
586 * Return: status code
588 static efi_status_t EFIAPI efi_cout_set_cursor_position(
589 struct efi_simple_text_output_protocol *this,
590 unsigned long column, unsigned long row)
592 efi_status_t ret = EFI_SUCCESS;
593 struct simple_text_output_mode *con = &efi_con_mode;
594 struct cout_mode *mode = &efi_cout_modes[con->mode];
596 EFI_ENTRY("%p, %ld, %ld", this, column, row);
598 /* Check parameters */
600 ret = EFI_INVALID_PARAMETER;
603 if (row >= mode->rows || column >= mode->columns) {
604 ret = EFI_UNSUPPORTED;
609 * Set cursor position by sending CSI H.
610 * EFI origin is [0, 0], terminal origin is [1, 1].
612 printf(ESC "[%d;%dH", (int)row + 1, (int)column + 1);
613 efi_con_mode.cursor_column = column;
614 efi_con_mode.cursor_row = row;
616 return EFI_EXIT(ret);
620 * efi_cout_enable_cursor() - enable the cursor
622 * This function implements the EnableCursor service of the simple text output
623 * protocol. See the Unified Extensible Firmware Interface (UEFI) specification
626 * @this: pointer to the protocol instance
627 * @enable: if true enable, if false disable the cursor
628 * Return: status code
630 static efi_status_t EFIAPI efi_cout_enable_cursor(
631 struct efi_simple_text_output_protocol *this,
634 EFI_ENTRY("%p, %d", this, enable);
636 printf(ESC"[?25%c", enable ? 'h' : 'l');
637 efi_con_mode.cursor_visible = !!enable;
639 return EFI_EXIT(EFI_SUCCESS);
642 struct efi_simple_text_output_protocol efi_con_out = {
643 .reset = efi_cout_reset,
644 .output_string = efi_cout_output_string,
645 .test_string = efi_cout_test_string,
646 .query_mode = efi_cout_query_mode,
647 .set_mode = efi_cout_set_mode,
648 .set_attribute = efi_cout_set_attribute,
649 .clear_screen = efi_cout_clear_screen,
650 .set_cursor_position = efi_cout_set_cursor_position,
651 .enable_cursor = efi_cout_enable_cursor,
652 .mode = (void*)&efi_con_mode,
656 * struct efi_cin_notify_function - registered console input notify function
658 * @link: link to list
659 * @key: key to notify
660 * @function: function to call
662 struct efi_cin_notify_function {
663 struct list_head link;
664 struct efi_key_data key;
665 efi_status_t (EFIAPI *function)
666 (struct efi_key_data *key_data);
669 static bool key_available;
670 static struct efi_key_data next_key;
671 static LIST_HEAD(cin_notify_functions);
674 * set_shift_mask() - set shift mask
676 * @mod: Xterm shift mask
677 * @key_state: receives the state of the shift, alt, control, and logo keys
679 static void set_shift_mask(int mod, struct efi_key_state *key_state)
681 key_state->key_shift_state = EFI_SHIFT_STATE_VALID;
685 key_state->key_shift_state |= EFI_LEFT_SHIFT_PRESSED;
687 key_state->key_shift_state |= EFI_LEFT_ALT_PRESSED;
689 key_state->key_shift_state |= EFI_LEFT_CONTROL_PRESSED;
690 if (!mod || (mod & 8))
691 key_state->key_shift_state |= EFI_LEFT_LOGO_PRESSED;
696 * analyze_modifiers() - analyze modifiers (shift, alt, ctrl) for function keys
698 * This gets called when we have already parsed CSI.
700 * @key_state: receives the state of the shift, alt, control, and logo keys
701 * Return: the unmodified code
703 static int analyze_modifiers(struct efi_key_state *key_state)
705 int c, mod = 0, ret = 0;
729 set_shift_mask(mod, key_state);
736 * efi_cin_read_key() - read a key from the console input
738 * @key: - key received
739 * Return: - status code
741 static efi_status_t efi_cin_read_key(struct efi_key_data *key)
743 struct efi_input_key pressed_key = {
749 if (console_read_unicode(&ch))
750 return EFI_NOT_READY;
752 key->key_state.key_shift_state = EFI_SHIFT_STATE_INVALID;
753 key->key_state.key_toggle_state = EFI_TOGGLE_STATE_INVALID;
755 /* We do not support multi-word codes */
762 * If a second key is received within 10 ms, assume that we are
763 * dealing with an escape sequence. Otherwise consider this the
764 * escape key being hit. 10 ms is long enough to work fine at
765 * 1200 baud and above.
769 pressed_key.scan_code = 23;
773 * Xterm Control Sequences
774 * https://www.xfree86.org/4.8.0/ctlseqs.html
779 pressed_key.scan_code = 23;
781 case 'O': /* F1 - F4, End */
783 /* consider modifiers */
784 if (ch == 'F') { /* End */
785 pressed_key.scan_code = 6;
787 } else if (ch < 'P') {
788 set_shift_mask(ch - '0', &key->key_state);
791 pressed_key.scan_code = ch - 'P' + 11;
796 case 'A'...'D': /* up, down right, left */
797 pressed_key.scan_code = ch - 'A' + 1;
800 pressed_key.scan_code = 6;
803 pressed_key.scan_code = 5;
806 ch = analyze_modifiers(&key->key_state);
808 case '1'...'5': /* F1 - F5 */
809 pressed_key.scan_code = ch - '1' + 11;
811 case '6'...'9': /* F5 - F8 */
812 pressed_key.scan_code = ch - '6' + 15;
814 case 'A'...'D': /* up, down right, left */
815 pressed_key.scan_code = ch - 'A' + 1;
818 pressed_key.scan_code = 6;
821 pressed_key.scan_code = 5;
824 pressed_key.scan_code = 5;
829 ch = analyze_modifiers(&key->key_state);
831 case '0'...'1': /* F9 - F10 */
832 pressed_key.scan_code = ch - '0' + 19;
834 case '3'...'4': /* F11 - F12 */
835 pressed_key.scan_code = ch - '3' + 21;
838 pressed_key.scan_code = 7;
843 pressed_key.scan_code = 8;
844 analyze_modifiers(&key->key_state);
846 case '5': /* PG UP */
847 pressed_key.scan_code = 9;
848 analyze_modifiers(&key->key_state);
850 case '6': /* PG DOWN */
851 pressed_key.scan_code = 10;
852 analyze_modifiers(&key->key_state);
858 set_shift_mask(3, &key->key_state);
865 if (pressed_key.scan_code) {
866 key->key_state.key_shift_state |= EFI_SHIFT_STATE_VALID;
868 pressed_key.unicode_char = ch;
871 * Assume left control key for control characters typically
872 * entered using the control key.
874 if (ch >= 0x01 && ch <= 0x1f) {
875 key->key_state.key_shift_state |=
876 EFI_SHIFT_STATE_VALID;
881 key->key_state.key_shift_state |=
882 EFI_LEFT_CONTROL_PRESSED;
886 key->key = pressed_key;
892 * efi_cin_notify() - notify registered functions
894 static void efi_cin_notify(void)
896 struct efi_cin_notify_function *item;
898 list_for_each_entry(item, &cin_notify_functions, link) {
901 /* We do not support toggle states */
902 if (item->key.key.unicode_char || item->key.key.scan_code) {
903 if (item->key.key.unicode_char !=
904 next_key.key.unicode_char ||
905 item->key.key.scan_code != next_key.key.scan_code)
908 if (item->key.key_state.key_shift_state &&
909 item->key.key_state.key_shift_state !=
910 next_key.key_state.key_shift_state)
914 /* We don't bother about the return code */
915 EFI_CALL(item->function(&next_key));
920 * efi_cin_check() - check if keyboard input is available
922 static void efi_cin_check(void)
927 efi_signal_event(efi_con_in.wait_for_key);
932 ret = efi_cin_read_key(&next_key);
933 if (ret == EFI_SUCCESS) {
934 key_available = true;
936 /* Notify registered functions */
939 /* Queue the wait for key event */
941 efi_signal_event(efi_con_in.wait_for_key);
947 * efi_cin_empty_buffer() - empty input buffer
949 static void efi_cin_empty_buffer(void)
953 key_available = false;
957 * efi_cin_reset_ex() - reset console input
959 * @this: - the extended simple text input protocol
960 * @extended_verification: - extended verification
962 * This function implements the reset service of the
963 * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
965 * See the Unified Extensible Firmware Interface (UEFI) specification for
968 * Return: old value of the task priority level
970 static efi_status_t EFIAPI efi_cin_reset_ex(
971 struct efi_simple_text_input_ex_protocol *this,
972 bool extended_verification)
974 efi_status_t ret = EFI_SUCCESS;
976 EFI_ENTRY("%p, %d", this, extended_verification);
978 /* Check parameters */
980 ret = EFI_INVALID_PARAMETER;
984 efi_cin_empty_buffer();
986 return EFI_EXIT(ret);
990 * efi_cin_read_key_stroke_ex() - read key stroke
992 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
993 * @key_data: key read from console
994 * Return: status code
996 * This function implements the ReadKeyStrokeEx service of the
997 * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
999 * See the Unified Extensible Firmware Interface (UEFI) specification for
1002 static efi_status_t EFIAPI efi_cin_read_key_stroke_ex(
1003 struct efi_simple_text_input_ex_protocol *this,
1004 struct efi_key_data *key_data)
1006 efi_status_t ret = EFI_SUCCESS;
1008 EFI_ENTRY("%p, %p", this, key_data);
1010 /* Check parameters */
1011 if (!this || !key_data) {
1012 ret = EFI_INVALID_PARAMETER;
1016 /* We don't do interrupts, so check for timers cooperatively */
1019 /* Enable console input after ExitBootServices */
1022 if (!key_available) {
1023 memset(key_data, 0, sizeof(struct efi_key_data));
1024 ret = EFI_NOT_READY;
1028 * CTRL+A - CTRL+Z have to be signaled as a - z.
1029 * SHIFT+CTRL+A - SHIFT+CTRL+Z have to be signaled as A - Z.
1030 * CTRL+\ - CTRL+_ have to be signaled as \ - _.
1032 switch (next_key.key.unicode_char) {
1036 if (!(next_key.key_state.key_toggle_state &
1037 EFI_CAPS_LOCK_ACTIVE) ^
1038 !(next_key.key_state.key_shift_state &
1039 (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)))
1040 next_key.key.unicode_char += 0x40;
1042 next_key.key.unicode_char += 0x60;
1045 next_key.key.unicode_char += 0x40;
1047 *key_data = next_key;
1048 key_available = false;
1049 efi_con_in.wait_for_key->is_signaled = false;
1052 return EFI_EXIT(ret);
1056 * efi_cin_set_state() - set toggle key state
1058 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1059 * @key_toggle_state: pointer to key toggle state
1060 * Return: status code
1062 * This function implements the SetState service of the
1063 * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
1065 * See the Unified Extensible Firmware Interface (UEFI) specification for
1068 static efi_status_t EFIAPI efi_cin_set_state(
1069 struct efi_simple_text_input_ex_protocol *this,
1070 u8 *key_toggle_state)
1072 EFI_ENTRY("%p, %p", this, key_toggle_state);
1074 * U-Boot supports multiple console input sources like serial and
1075 * net console for which a key toggle state cannot be set at all.
1077 * According to the UEFI specification it is allowable to not implement
1080 return EFI_EXIT(EFI_UNSUPPORTED);
1084 * efi_cin_register_key_notify() - register key notification function
1086 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1087 * @key_data: key to be notified
1088 * @key_notify_function: function to be called if the key is pressed
1089 * @notify_handle: handle for unregistering the notification
1090 * Return: status code
1092 * This function implements the SetState service of the
1093 * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
1095 * See the Unified Extensible Firmware Interface (UEFI) specification for
1098 static efi_status_t EFIAPI efi_cin_register_key_notify(
1099 struct efi_simple_text_input_ex_protocol *this,
1100 struct efi_key_data *key_data,
1101 efi_status_t (EFIAPI *key_notify_function)(
1102 struct efi_key_data *key_data),
1103 void **notify_handle)
1105 efi_status_t ret = EFI_SUCCESS;
1106 struct efi_cin_notify_function *notify_function;
1108 EFI_ENTRY("%p, %p, %p, %p",
1109 this, key_data, key_notify_function, notify_handle);
1111 /* Check parameters */
1112 if (!this || !key_data || !key_notify_function || !notify_handle) {
1113 ret = EFI_INVALID_PARAMETER;
1117 EFI_PRINT("u+%04x, sc %04x, sh %08x, tg %02x\n",
1118 key_data->key.unicode_char,
1119 key_data->key.scan_code,
1120 key_data->key_state.key_shift_state,
1121 key_data->key_state.key_toggle_state);
1123 notify_function = calloc(1, sizeof(struct efi_cin_notify_function));
1124 if (!notify_function) {
1125 ret = EFI_OUT_OF_RESOURCES;
1128 notify_function->key = *key_data;
1129 notify_function->function = key_notify_function;
1130 list_add_tail(¬ify_function->link, &cin_notify_functions);
1131 *notify_handle = notify_function;
1133 return EFI_EXIT(ret);
1137 * efi_cin_unregister_key_notify() - unregister key notification function
1139 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1140 * @notification_handle: handle received when registering
1141 * Return: status code
1143 * This function implements the SetState service of the
1144 * EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
1146 * See the Unified Extensible Firmware Interface (UEFI) specification for
1149 static efi_status_t EFIAPI efi_cin_unregister_key_notify(
1150 struct efi_simple_text_input_ex_protocol *this,
1151 void *notification_handle)
1153 efi_status_t ret = EFI_INVALID_PARAMETER;
1154 struct efi_cin_notify_function *item, *notify_function =
1155 notification_handle;
1157 EFI_ENTRY("%p, %p", this, notification_handle);
1159 /* Check parameters */
1160 if (!this || !notification_handle)
1163 list_for_each_entry(item, &cin_notify_functions, link) {
1164 if (item == notify_function) {
1169 if (ret != EFI_SUCCESS)
1172 /* Remove the notify function */
1173 list_del(¬ify_function->link);
1174 free(notify_function);
1176 return EFI_EXIT(ret);
1180 * efi_cin_reset() - drain the input buffer
1182 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1183 * @extended_verification: allow for exhaustive verification
1184 * Return: status code
1186 * This function implements the Reset service of the
1187 * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
1189 * See the Unified Extensible Firmware Interface (UEFI) specification for
1192 static efi_status_t EFIAPI efi_cin_reset
1193 (struct efi_simple_text_input_protocol *this,
1194 bool extended_verification)
1196 efi_status_t ret = EFI_SUCCESS;
1198 EFI_ENTRY("%p, %d", this, extended_verification);
1200 /* Check parameters */
1202 ret = EFI_INVALID_PARAMETER;
1206 efi_cin_empty_buffer();
1208 return EFI_EXIT(ret);
1212 * efi_cin_read_key_stroke() - read key stroke
1214 * @this: instance of the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1215 * @key: key read from console
1216 * Return: status code
1218 * This function implements the ReadKeyStroke service of the
1219 * EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
1221 * See the Unified Extensible Firmware Interface (UEFI) specification for
1224 static efi_status_t EFIAPI efi_cin_read_key_stroke
1225 (struct efi_simple_text_input_protocol *this,
1226 struct efi_input_key *key)
1228 efi_status_t ret = EFI_SUCCESS;
1230 EFI_ENTRY("%p, %p", this, key);
1232 /* Check parameters */
1233 if (!this || !key) {
1234 ret = EFI_INVALID_PARAMETER;
1238 /* We don't do interrupts, so check for timers cooperatively */
1241 /* Enable console input after ExitBootServices */
1244 if (!key_available) {
1245 ret = EFI_NOT_READY;
1248 *key = next_key.key;
1249 key_available = false;
1250 efi_con_in.wait_for_key->is_signaled = false;
1252 return EFI_EXIT(ret);
1255 static struct efi_simple_text_input_ex_protocol efi_con_in_ex = {
1256 .reset = efi_cin_reset_ex,
1257 .read_key_stroke_ex = efi_cin_read_key_stroke_ex,
1258 .wait_for_key_ex = NULL,
1259 .set_state = efi_cin_set_state,
1260 .register_key_notify = efi_cin_register_key_notify,
1261 .unregister_key_notify = efi_cin_unregister_key_notify,
1264 struct efi_simple_text_input_protocol efi_con_in = {
1265 .reset = efi_cin_reset,
1266 .read_key_stroke = efi_cin_read_key_stroke,
1267 .wait_for_key = NULL,
1270 static struct efi_event *console_timer_event;
1273 * efi_console_timer_notify() - notify the console timer event
1275 * @event: console timer event
1276 * @context: not used
1278 static void EFIAPI efi_console_timer_notify(struct efi_event *event,
1281 EFI_ENTRY("%p, %p", event, context);
1283 EFI_EXIT(EFI_SUCCESS);
1287 * efi_key_notify() - notify the wait for key event
1289 * @event: wait for key event
1290 * @context: not used
1292 static void EFIAPI efi_key_notify(struct efi_event *event, void *context)
1294 EFI_ENTRY("%p, %p", event, context);
1296 EFI_EXIT(EFI_SUCCESS);
1300 * efi_console_register() - install the console protocols
1302 * This function is called from do_bootefi_exec().
1304 * Return: status code
1306 efi_status_t efi_console_register(void)
1309 struct efi_device_path *dp;
1311 /* Install protocols on root node */
1312 r = efi_install_multiple_protocol_interfaces(&efi_root,
1313 &efi_guid_text_output_protocol,
1315 &efi_guid_text_input_protocol,
1317 &efi_guid_text_input_ex_protocol,
1321 /* Create console node and install device path protocols */
1322 if (CONFIG_IS_ENABLED(DM_SERIAL)) {
1323 dp = efi_dp_from_uart();
1327 /* Hook UART up to the device list */
1328 efi_add_handle(&uart_obj);
1330 /* Install device path */
1331 r = efi_add_protocol(&uart_obj, &efi_guid_device_path, dp);
1332 if (r != EFI_SUCCESS)
1336 /* Create console events */
1337 r = efi_create_event(EVT_NOTIFY_WAIT, TPL_CALLBACK, efi_key_notify,
1338 NULL, NULL, &efi_con_in.wait_for_key);
1339 if (r != EFI_SUCCESS) {
1340 printf("ERROR: Failed to register WaitForKey event\n");
1343 efi_con_in_ex.wait_for_key_ex = efi_con_in.wait_for_key;
1344 r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
1345 efi_console_timer_notify, NULL, NULL,
1346 &console_timer_event);
1347 if (r != EFI_SUCCESS) {
1348 printf("ERROR: Failed to register console event\n");
1351 /* 5000 ns cycle is sufficient for 2 MBaud */
1352 r = efi_set_timer(console_timer_event, EFI_TIMER_PERIODIC, 50);
1353 if (r != EFI_SUCCESS)
1354 printf("ERROR: Failed to set console timer\n");
1357 printf("ERROR: Out of memory\n");
1362 * efi_console_get_u16_string() - get user input string
1364 * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL
1365 * @buf: buffer to store user input string in UTF16
1366 * @count: number of u16 string including NULL terminator that buf has
1367 * @filter_func: callback to filter user input
1368 * @row: row number to locate user input form
1369 * @col: column number to locate user input form
1370 * Return: status code
1372 efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin,
1373 u16 *buf, efi_uintn_t count,
1374 efi_console_filter_func filter_func,
1378 efi_uintn_t len = 0;
1379 struct efi_input_key key;
1381 printf(ANSI_CURSOR_POSITION
1382 ANSI_CLEAR_LINE_TO_END
1383 ANSI_CURSOR_SHOW, row, col);
1385 efi_cin_empty_buffer();
1389 ret = EFI_CALL(cin->read_key_stroke(cin, &key));
1391 } while (ret == EFI_NOT_READY);
1393 if (key.unicode_char == u'\b') {
1397 printf(ANSI_CURSOR_POSITION
1399 ANSI_CLEAR_LINE_TO_END, row, col, buf);
1401 } else if (key.unicode_char == u'\r') {
1404 } else if (key.unicode_char == 0x3 || key.scan_code == 23) {
1406 } else if (key.unicode_char < 0x20) {
1407 /* ignore control codes other than Ctrl+C, '\r' and '\b' */
1409 } else if (key.scan_code != 0) {
1410 /* only accept single ESC press for cancel */
1415 if (filter_func(&key) != EFI_SUCCESS)
1419 if (len >= (count - 1))
1422 buf[len] = key.unicode_char;
1424 printf(ANSI_CURSOR_POSITION "%ls", row, col, buf);