]> Git Repo - qemu.git/blob - tests/endianness-test.c
tests/qapi-schema: Cover union types with base
[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 <[email protected]>
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
14 #include <glib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19
20 #include "libqtest.h"
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 }
This page took 0.042213 seconds and 4 git commands to generate.