summaryrefslogtreecommitdiffstats
path: root/lib/efi_selftest/efi_selftest_textoutput.c
blob: a87f65e197fea1eea71a69524c2f68d54b53c295 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: GPL-2.0+
/*
 * efi_selftest_textoutput
 *
 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
 *
 * Test the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
 *
 * The following services are tested:
 * OutputString, TestString, SetAttribute.
 */

#include <efi_selftest.h>

/*
 * Execute unit test.
 *
 * @return:	EFI_ST_SUCCESS for success
 */
static int execute(void)
{
	size_t foreground;
	size_t background;
	size_t attrib;
	efi_status_t ret;
	s16 col;
	u16 cr[] = { 0x0d, 0x00 };
	u16 lf[] = { 0x0a, 0x00 };
	u16 brahmi[] = { /* 2 Brahmi letters */
		0xD804, 0xDC05,
		0xD804, 0xDC22,
		0};

	/* SetAttribute */
	efi_st_printf("\nColor palette\n");
	for (foreground = 0; foreground < 0x10; ++foreground) {
		for (background = 0; background < 0x80; background += 0x10) {
			attrib = foreground | background;
			con_out->set_attribute(con_out, attrib);
			efi_st_printf("%p", (void *)attrib);
		}
		con_out->set_attribute(con_out, 0);
		efi_st_printf("\n");
	}
	/* TestString */
	ret = con_out->test_string(con_out,
			L" !\"#$%&'()*+,-./0-9:;<=>?@A-Z[\\]^_`a-z{|}~\n");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("TestString failed for ANSI characters\n");
		return EFI_ST_FAILURE;
	}
	/* OutputString */
	ret = con_out->output_string(con_out,
				     L"Testing cursor column update\n");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for ANSI characters");
		return EFI_ST_FAILURE;
	}
	col = con_out->mode->cursor_column;
	ret = con_out->output_string(con_out, lf);
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for line feed\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column != col) {
		efi_st_error("Cursor column changed by line feed\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, cr);
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for carriage return\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column) {
		efi_st_error("Cursor column not 0 at beginning of line\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, L"123");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for ANSI characters\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column != 3) {
		efi_st_error("Cursor column not incremented properly\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, L"\b");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for backspace\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column != 2) {
		efi_st_error("Cursor column not decremented properly\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, L"\b\b");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for backspace\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column) {
		efi_st_error("Cursor column not decremented properly\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, L"\b\b");
	if (ret != EFI_ST_SUCCESS) {
		efi_st_error("OutputString failed for backspace\n");
		return EFI_ST_FAILURE;
	}
	if (con_out->mode->cursor_column) {
		efi_st_error("Cursor column decremented past zero\n");
		return EFI_ST_FAILURE;
	}
	ret = con_out->output_string(con_out, brahmi);
	if (ret != EFI_ST_SUCCESS) {
		efi_st_todo("Unicode output not fully supported\n");
	} else if (con_out->mode->cursor_column != 2) {
		efi_st_printf("Unicode not handled properly\n");
		return EFI_ST_FAILURE;
	}
	efi_st_printf("\n");

	return EFI_ST_SUCCESS;
}

EFI_UNIT_TEST(textoutput) = {
	.name = "text output",
	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
	.execute = execute,
};