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