]> git.proxmox.com Git - qemu.git/blob - tests/endianness-test.c
acpi-build: fix build on glib < 2.22
[qemu.git] / tests / endianness-test.c
1 /*
2 * QTest testcase for ISA endianness
3 *
4 * Copyright Red Hat, Inc. 2012
5 *
6 * Authors:
7 * Paolo Bonzini <pbonzini@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 *
12 */
13 #include "libqtest.h"
14
15 #include <glib.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #include "qemu/bswap.h"
22
23 typedef struct TestCase TestCase;
24 struct TestCase {
25 const char *arch;
26 const char *machine;
27 uint64_t isa_base;
28 bool bswap;
29 const char *superio;
30 };
31
32 static const TestCase test_cases[] = {
33 { "i386", "pc", -1 },
34 { "mips", "magnum", 0x90000000, .bswap = true },
35 { "mips", "pica61", 0x90000000, .bswap = true },
36 { "mips", "mips", 0x14000000, .bswap = true },
37 { "mips", "malta", 0x10000000, .bswap = true },
38 { "mips64", "magnum", 0x90000000, .bswap = true },
39 { "mips64", "pica61", 0x90000000, .bswap = true },
40 { "mips64", "mips", 0x14000000, .bswap = true },
41 { "mips64", "malta", 0x10000000, .bswap = true },
42 { "mips64el", "fulong2e", 0x1fd00000 },
43 { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" },
44 { "ppc", "prep", 0x80000000, .bswap = true },
45 { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
46 { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" },
47 { "ppc64", "pseries", 0x10080000000ULL,
48 .bswap = true, .superio = "i82378" },
49 { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
50 { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
51 { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
52 { "x86_64", "pc", -1 },
53 {}
54 };
55
56 static uint8_t isa_inb(const TestCase *test, uint16_t addr)
57 {
58 uint8_t value;
59 if (test->isa_base == -1) {
60 value = inb(addr);
61 } else {
62 value = readb(test->isa_base + addr);
63 }
64 return value;
65 }
66
67 static uint16_t isa_inw(const TestCase *test, uint16_t addr)
68 {
69 uint16_t value;
70 if (test->isa_base == -1) {
71 value = inw(addr);
72 } else {
73 value = readw(test->isa_base + addr);
74 }
75 return test->bswap ? bswap16(value) : value;
76 }
77
78 static uint32_t isa_inl(const TestCase *test, uint16_t addr)
79 {
80 uint32_t value;
81 if (test->isa_base == -1) {
82 value = inl(addr);
83 } else {
84 value = readl(test->isa_base + addr);
85 }
86 return test->bswap ? bswap32(value) : value;
87 }
88
89 static void isa_outb(const TestCase *test, uint16_t addr, uint8_t value)
90 {
91 if (test->isa_base == -1) {
92 outb(addr, value);
93 } else {
94 writeb(test->isa_base + addr, value);
95 }
96 }
97
98 static void isa_outw(const TestCase *test, uint16_t addr, uint16_t value)
99 {
100 value = test->bswap ? bswap16(value) : value;
101 if (test->isa_base == -1) {
102 outw(addr, value);
103 } else {
104 writew(test->isa_base + addr, value);
105 }
106 }
107
108 static void isa_outl(const TestCase *test, uint16_t addr, uint32_t value)
109 {
110 value = test->bswap ? bswap32(value) : value;
111 if (test->isa_base == -1) {
112 outl(addr, value);
113 } else {
114 writel(test->isa_base + addr, value);
115 }
116 }
117
118
119 static void test_endianness(gconstpointer data)
120 {
121 const TestCase *test = data;
122 char *args;
123
124 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
125 test->machine,
126 test->superio ? " -device " : "",
127 test->superio ?: "");
128 qtest_start(args);
129 isa_outl(test, 0xe0, 0x87654321);
130 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
131 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
132 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
133 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
134 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
135 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
136 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
137
138 isa_outw(test, 0xe2, 0x8866);
139 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
140 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
141 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
142 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
143 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
144 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
145 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
146
147 isa_outw(test, 0xe0, 0x4422);
148 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
149 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
150 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
151 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
152 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
153 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
154 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
155
156 isa_outb(test, 0xe3, 0x87);
157 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
158 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
159 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
160 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
161 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
162 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
163
164 isa_outb(test, 0xe2, 0x65);
165 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
166 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
167 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
168 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
169 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
170 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
171 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
172
173 isa_outb(test, 0xe1, 0x43);
174 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
175 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
176 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
177 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
178 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
179 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
180 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
181
182 isa_outb(test, 0xe0, 0x21);
183 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
184 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
185 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
186 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
187 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
188 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
189 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
190 qtest_quit(global_qtest);
191 g_free(args);
192 }
193
194 static void test_endianness_split(gconstpointer data)
195 {
196 const TestCase *test = data;
197 char *args;
198
199 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
200 test->machine,
201 test->superio ? " -device " : "",
202 test->superio ?: "");
203 qtest_start(args);
204 isa_outl(test, 0xe8, 0x87654321);
205 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
206 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
207 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
208
209 isa_outw(test, 0xea, 0x8866);
210 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
211 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
212 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
213
214 isa_outw(test, 0xe8, 0x4422);
215 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
216 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
217 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
218
219 isa_outb(test, 0xeb, 0x87);
220 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
221 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
222
223 isa_outb(test, 0xea, 0x65);
224 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
225 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
226 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
227
228 isa_outb(test, 0xe9, 0x43);
229 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
230 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
231 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
232
233 isa_outb(test, 0xe8, 0x21);
234 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
235 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
236 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
237 qtest_quit(global_qtest);
238 g_free(args);
239 }
240
241 static void test_endianness_combine(gconstpointer data)
242 {
243 const TestCase *test = data;
244 char *args;
245
246 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
247 test->machine,
248 test->superio ? " -device " : "",
249 test->superio ?: "");
250 qtest_start(args);
251 isa_outl(test, 0xe0, 0x87654321);
252 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
253 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
254 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
255
256 isa_outw(test, 0xe2, 0x8866);
257 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664321);
258 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
259 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
260
261 isa_outw(test, 0xe0, 0x4422);
262 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664422);
263 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
264 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
265
266 isa_outb(test, 0xe3, 0x87);
267 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87664422);
268 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8766);
269
270 isa_outb(test, 0xe2, 0x65);
271 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654422);
272 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
273 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
274
275 isa_outb(test, 0xe1, 0x43);
276 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654322);
277 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
278 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4322);
279
280 isa_outb(test, 0xe0, 0x21);
281 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
282 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
283 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
284 qtest_quit(global_qtest);
285 g_free(args);
286 }
287
288 int main(int argc, char **argv)
289 {
290 const char *arch = qtest_get_arch();
291 int ret;
292 int i;
293
294 g_test_init(&argc, &argv, NULL);
295
296 for (i = 0; test_cases[i].arch; i++) {
297 gchar *path;
298 if (strcmp(test_cases[i].arch, arch) != 0) {
299 continue;
300 }
301 path = g_strdup_printf("/%s/endianness/%s",
302 arch, test_cases[i].machine);
303 g_test_add_data_func(path, &test_cases[i], test_endianness);
304
305 path = g_strdup_printf("/%s/endianness/split/%s",
306 arch, test_cases[i].machine);
307 g_test_add_data_func(path, &test_cases[i], test_endianness_split);
308
309 path = g_strdup_printf("/%s/endianness/combine/%s",
310 arch, test_cases[i].machine);
311 g_test_add_data_func(path, &test_cases[i], test_endianness_combine);
312 }
313
314 ret = g_test_run();
315
316 return ret;
317 }