183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
20aa2da78SHeinrich Schuchardt /*
30aa2da78SHeinrich Schuchardt  * efi_selftest_textinput
40aa2da78SHeinrich Schuchardt  *
50aa2da78SHeinrich Schuchardt  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
60aa2da78SHeinrich Schuchardt  *
70aa2da78SHeinrich Schuchardt  * Provides a unit test for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
8*d8b2216cSHeinrich Schuchardt  * The Unicode character and the scan code are printed for text
90aa2da78SHeinrich Schuchardt  * input. To run the test:
100aa2da78SHeinrich Schuchardt  *
110aa2da78SHeinrich Schuchardt  *	setenv efi_selftest text input
120aa2da78SHeinrich Schuchardt  *	bootefi selftest
130aa2da78SHeinrich Schuchardt  */
140aa2da78SHeinrich Schuchardt 
150aa2da78SHeinrich Schuchardt #include <efi_selftest.h>
160aa2da78SHeinrich Schuchardt 
170aa2da78SHeinrich Schuchardt static struct efi_boot_services *boottime;
180aa2da78SHeinrich Schuchardt 
190aa2da78SHeinrich Schuchardt /*
200aa2da78SHeinrich Schuchardt  * Setup unit test.
210aa2da78SHeinrich Schuchardt  *
220aa2da78SHeinrich Schuchardt  * @handle:	handle of the loaded image
230aa2da78SHeinrich Schuchardt  * @systable:	system table
240aa2da78SHeinrich Schuchardt  * @return:	EFI_ST_SUCCESS for success
250aa2da78SHeinrich Schuchardt  */
setup(const efi_handle_t handle,const struct efi_system_table * systable)260aa2da78SHeinrich Schuchardt static int setup(const efi_handle_t handle,
270aa2da78SHeinrich Schuchardt 		 const struct efi_system_table *systable)
280aa2da78SHeinrich Schuchardt {
290aa2da78SHeinrich Schuchardt 	boottime = systable->boottime;
300aa2da78SHeinrich Schuchardt 
310aa2da78SHeinrich Schuchardt 	return EFI_ST_SUCCESS;
320aa2da78SHeinrich Schuchardt }
330aa2da78SHeinrich Schuchardt 
340aa2da78SHeinrich Schuchardt /*
350aa2da78SHeinrich Schuchardt  * Execute unit test.
360aa2da78SHeinrich Schuchardt  *
370aa2da78SHeinrich Schuchardt  * @return:	EFI_ST_SUCCESS for success
380aa2da78SHeinrich Schuchardt  */
execute(void)390aa2da78SHeinrich Schuchardt static int execute(void)
400aa2da78SHeinrich Schuchardt {
410aa2da78SHeinrich Schuchardt 	struct efi_input_key input_key = {0};
420aa2da78SHeinrich Schuchardt 	efi_status_t ret;
431d69c8d8SHeinrich Schuchardt 	efi_uintn_t index;
441d69c8d8SHeinrich Schuchardt 
451d69c8d8SHeinrich Schuchardt 	/* Drain the console input */
461d69c8d8SHeinrich Schuchardt 	ret = con_in->reset(con_in, true);
471d69c8d8SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
481d69c8d8SHeinrich Schuchardt 		efi_st_error("Reset failed\n");
491d69c8d8SHeinrich Schuchardt 		return EFI_ST_FAILURE;
501d69c8d8SHeinrich Schuchardt 	}
511d69c8d8SHeinrich Schuchardt 	ret = con_in->read_key_stroke(con_in, &input_key);
521d69c8d8SHeinrich Schuchardt 	if (ret != EFI_NOT_READY) {
531d69c8d8SHeinrich Schuchardt 		efi_st_error("Empty buffer not reported\n");
541d69c8d8SHeinrich Schuchardt 		return EFI_ST_FAILURE;
551d69c8d8SHeinrich Schuchardt 	}
560aa2da78SHeinrich Schuchardt 
570aa2da78SHeinrich Schuchardt 	efi_st_printf("Waiting for your input\n");
580aa2da78SHeinrich Schuchardt 	efi_st_printf("To terminate type 'x'\n");
590aa2da78SHeinrich Schuchardt 
600aa2da78SHeinrich Schuchardt 	for (;;) {
610aa2da78SHeinrich Schuchardt 		/* Wait for next key */
621d69c8d8SHeinrich Schuchardt 		ret = boottime->wait_for_event(1, &con_in->wait_for_key,
631d69c8d8SHeinrich Schuchardt 					       &index);
641d69c8d8SHeinrich Schuchardt 		if (ret != EFI_ST_SUCCESS) {
651d69c8d8SHeinrich Schuchardt 			efi_st_error("WaitForEvent failed\n");
661d69c8d8SHeinrich Schuchardt 			return EFI_ST_FAILURE;
671d69c8d8SHeinrich Schuchardt 		}
680aa2da78SHeinrich Schuchardt 		ret = con_in->read_key_stroke(con_in, &input_key);
691d69c8d8SHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
701d69c8d8SHeinrich Schuchardt 			efi_st_error("ReadKeyStroke failed\n");
711d69c8d8SHeinrich Schuchardt 			return EFI_ST_FAILURE;
721d69c8d8SHeinrich Schuchardt 		}
730aa2da78SHeinrich Schuchardt 
740aa2da78SHeinrich Schuchardt 		/* Allow 5 minutes until time out */
750aa2da78SHeinrich Schuchardt 		boottime->set_watchdog_timer(300, 0, 0, NULL);
760aa2da78SHeinrich Schuchardt 
770aa2da78SHeinrich Schuchardt 		efi_st_printf("Unicode char %u (%ps), scan code %u (%ps)\n",
780aa2da78SHeinrich Schuchardt 			      (unsigned int)input_key.unicode_char,
79262ff411SHeinrich Schuchardt 			      efi_st_translate_char(input_key.unicode_char),
800aa2da78SHeinrich Schuchardt 			      (unsigned int)input_key.scan_code,
81262ff411SHeinrich Schuchardt 			      efi_st_translate_code(input_key.scan_code));
820aa2da78SHeinrich Schuchardt 
830aa2da78SHeinrich Schuchardt 		switch (input_key.unicode_char) {
840aa2da78SHeinrich Schuchardt 		case 'x':
850aa2da78SHeinrich Schuchardt 		case 'X':
860aa2da78SHeinrich Schuchardt 			return EFI_ST_SUCCESS;
870aa2da78SHeinrich Schuchardt 		}
880aa2da78SHeinrich Schuchardt 	}
890aa2da78SHeinrich Schuchardt }
900aa2da78SHeinrich Schuchardt 
910aa2da78SHeinrich Schuchardt EFI_UNIT_TEST(textinput) = {
920aa2da78SHeinrich Schuchardt 	.name = "text input",
930aa2da78SHeinrich Schuchardt 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
940aa2da78SHeinrich Schuchardt 	.setup = setup,
950aa2da78SHeinrich Schuchardt 	.execute = execute,
960aa2da78SHeinrich Schuchardt 	.on_request = true,
970aa2da78SHeinrich Schuchardt };
98