1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * efi_selftest_textinput 4 * 5 * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> 6 * 7 * Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL. 8 * The Unicode character and the scan code are printed for text 9 * input. To run the test: 10 * 11 * setenv efi_selftest text input 12 * bootefi selftest 13 */ 14 15 #include <efi_selftest.h> 16 17 static struct efi_boot_services *boottime; 18 19 /* 20 * Setup unit test. 21 * 22 * @handle: handle of the loaded image 23 * @systable: system table 24 * @return: EFI_ST_SUCCESS for success 25 */ 26 static int setup(const efi_handle_t handle, 27 const struct efi_system_table *systable) 28 { 29 boottime = systable->boottime; 30 31 return EFI_ST_SUCCESS; 32 } 33 34 /* 35 * Execute unit test. 36 * 37 * @return: EFI_ST_SUCCESS for success 38 */ 39 static int execute(void) 40 { 41 struct efi_input_key input_key = {0}; 42 efi_status_t ret; 43 efi_uintn_t index; 44 45 /* Drain the console input */ 46 ret = con_in->reset(con_in, true); 47 if (ret != EFI_SUCCESS) { 48 efi_st_error("Reset failed\n"); 49 return EFI_ST_FAILURE; 50 } 51 ret = con_in->read_key_stroke(con_in, &input_key); 52 if (ret != EFI_NOT_READY) { 53 efi_st_error("Empty buffer not reported\n"); 54 return EFI_ST_FAILURE; 55 } 56 57 efi_st_printf("Waiting for your input\n"); 58 efi_st_printf("To terminate type 'x'\n"); 59 60 for (;;) { 61 /* Wait for next key */ 62 ret = boottime->wait_for_event(1, &con_in->wait_for_key, 63 &index); 64 if (ret != EFI_ST_SUCCESS) { 65 efi_st_error("WaitForEvent failed\n"); 66 return EFI_ST_FAILURE; 67 } 68 ret = con_in->read_key_stroke(con_in, &input_key); 69 if (ret != EFI_SUCCESS) { 70 efi_st_error("ReadKeyStroke failed\n"); 71 return EFI_ST_FAILURE; 72 } 73 74 /* Allow 5 minutes until time out */ 75 boottime->set_watchdog_timer(300, 0, 0, NULL); 76 77 efi_st_printf("Unicode char %u (%ps), scan code %u (%ps)\n", 78 (unsigned int)input_key.unicode_char, 79 efi_st_translate_char(input_key.unicode_char), 80 (unsigned int)input_key.scan_code, 81 efi_st_translate_code(input_key.scan_code)); 82 83 switch (input_key.unicode_char) { 84 case 'x': 85 case 'X': 86 return EFI_ST_SUCCESS; 87 } 88 } 89 } 90 91 EFI_UNIT_TEST(textinput) = { 92 .name = "text input", 93 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, 94 .setup = setup, 95 .execute = execute, 96 .on_request = true, 97 }; 98