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