root / tests / endianness-test.c @ dc364f4c
History | View | Annotate | Download (10.5 kB)
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 |
} |