1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * efi_selftest_textoutput
4 *
5 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
6 *
7 * Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
8 *
9 * The following services are tested:
10 * OutputString, TestString, SetAttribute.
11 */
12
13 #include <efi_selftest.h>
14
15 /*
16 * Execute unit test.
17 *
18 * @return: EFI_ST_SUCCESS for success
19 */
execute(void)20 static int execute(void)
21 {
22 size_t foreground;
23 size_t background;
24 size_t attrib;
25 efi_status_t ret;
26 s16 col;
27 u16 cr[] = { 0x0d, 0x00 };
28 u16 lf[] = { 0x0a, 0x00 };
29 u16 brahmi[] = { /* 2 Brahmi letters */
30 0xD804, 0xDC05,
31 0xD804, 0xDC22,
32 0};
33
34 /* SetAttribute */
35 efi_st_printf("\nColor palette\n");
36 for (foreground = 0; foreground < 0x10; ++foreground) {
37 for (background = 0; background < 0x80; background += 0x10) {
38 attrib = foreground | background;
39 con_out->set_attribute(con_out, attrib);
40 efi_st_printf("%p", (void *)attrib);
41 }
42 con_out->set_attribute(con_out, 0);
43 efi_st_printf("\n");
44 }
45 /* TestString */
46 ret = con_out->test_string(con_out,
47 L" !\"#$%&'()*+,-./0-9:;<=>?@A-Z[\\]^_`a-z{|}~\n");
48 if (ret != EFI_ST_SUCCESS) {
49 efi_st_error("TestString failed for ANSI characters\n");
50 return EFI_ST_FAILURE;
51 }
52 /* OutputString */
53 ret = con_out->output_string(con_out,
54 L"Testing cursor column update\n");
55 if (ret != EFI_ST_SUCCESS) {
56 efi_st_error("OutputString failed for ANSI characters");
57 return EFI_ST_FAILURE;
58 }
59 col = con_out->mode->cursor_column;
60 ret = con_out->output_string(con_out, lf);
61 if (ret != EFI_ST_SUCCESS) {
62 efi_st_error("OutputString failed for line feed\n");
63 return EFI_ST_FAILURE;
64 }
65 if (con_out->mode->cursor_column != col) {
66 efi_st_error("Cursor column changed by line feed\n");
67 return EFI_ST_FAILURE;
68 }
69 ret = con_out->output_string(con_out, cr);
70 if (ret != EFI_ST_SUCCESS) {
71 efi_st_error("OutputString failed for carriage return\n");
72 return EFI_ST_FAILURE;
73 }
74 if (con_out->mode->cursor_column) {
75 efi_st_error("Cursor column not 0 at beginning of line\n");
76 return EFI_ST_FAILURE;
77 }
78 ret = con_out->output_string(con_out, L"123");
79 if (ret != EFI_ST_SUCCESS) {
80 efi_st_error("OutputString failed for ANSI characters\n");
81 return EFI_ST_FAILURE;
82 }
83 if (con_out->mode->cursor_column != 3) {
84 efi_st_error("Cursor column not incremented properly\n");
85 return EFI_ST_FAILURE;
86 }
87 ret = con_out->output_string(con_out, L"\b");
88 if (ret != EFI_ST_SUCCESS) {
89 efi_st_error("OutputString failed for backspace\n");
90 return EFI_ST_FAILURE;
91 }
92 if (con_out->mode->cursor_column != 2) {
93 efi_st_error("Cursor column not decremented properly\n");
94 return EFI_ST_FAILURE;
95 }
96 ret = con_out->output_string(con_out, L"\b\b");
97 if (ret != EFI_ST_SUCCESS) {
98 efi_st_error("OutputString failed for backspace\n");
99 return EFI_ST_FAILURE;
100 }
101 if (con_out->mode->cursor_column) {
102 efi_st_error("Cursor column not decremented properly\n");
103 return EFI_ST_FAILURE;
104 }
105 ret = con_out->output_string(con_out, L"\b\b");
106 if (ret != EFI_ST_SUCCESS) {
107 efi_st_error("OutputString failed for backspace\n");
108 return EFI_ST_FAILURE;
109 }
110 if (con_out->mode->cursor_column) {
111 efi_st_error("Cursor column decremented past zero\n");
112 return EFI_ST_FAILURE;
113 }
114 ret = con_out->output_string(con_out, brahmi);
115 if (ret != EFI_ST_SUCCESS) {
116 efi_st_todo("Unicode output not fully supported\n");
117 } else if (con_out->mode->cursor_column != 2) {
118 efi_st_printf("Unicode not handled properly\n");
119 return EFI_ST_FAILURE;
120 }
121 efi_st_printf("\n");
122
123 return EFI_ST_SUCCESS;
124 }
125
126 EFI_UNIT_TEST(textoutput) = {
127 .name = "text output",
128 .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
129 .execute = execute,
130 };
131