2 * QTest testcase for ISA endianness
4 * Copyright Red Hat, Inc. 2012
7 * Paolo Bonzini <pbonzini@redhat.com>
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.
14 #include "qemu/osdep.h"
18 #include "qemu/bswap.h"
20 typedef struct TestCase TestCase;
29 static const TestCase test_cases[] = {
31 { "mips", "mips", 0x14000000, .bswap = true },
32 { "mips", "malta", 0x10000000, .bswap = true },
33 { "mips64", "magnum", 0x90000000, .bswap = true },
34 { "mips64", "pica61", 0x90000000, .bswap = true },
35 { "mips64", "mips", 0x14000000, .bswap = true },
36 { "mips64", "malta", 0x10000000, .bswap = true },
37 { "mips64el", "fulong2e", 0x1fd00000 },
38 { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" },
39 { "ppc", "prep", 0x80000000, .bswap = true },
40 { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
41 { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" },
42 { "ppc64", "pseries", 0x10080000000ULL,
43 .bswap = true, .superio = "i82378" },
44 { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
45 { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
46 { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
47 { "x86_64", "pc", -1 },
51 static uint8_t isa_inb(const TestCase *test, uint16_t addr)
54 if (test->isa_base == -1) {
57 value = readb(test->isa_base + addr);
62 static uint16_t isa_inw(const TestCase *test, uint16_t addr)
65 if (test->isa_base == -1) {
68 value = readw(test->isa_base + addr);
70 return test->bswap ? bswap16(value) : value;
73 static uint32_t isa_inl(const TestCase *test, uint16_t addr)
76 if (test->isa_base == -1) {
79 value = readl(test->isa_base + addr);
81 return test->bswap ? bswap32(value) : value;
84 static void isa_outb(const TestCase *test, uint16_t addr, uint8_t value)
86 if (test->isa_base == -1) {
89 writeb(test->isa_base + addr, value);
93 static void isa_outw(const TestCase *test, uint16_t addr, uint16_t value)
95 value = test->bswap ? bswap16(value) : value;
96 if (test->isa_base == -1) {
99 writew(test->isa_base + addr, value);
103 static void isa_outl(const TestCase *test, uint16_t addr, uint32_t value)
105 value = test->bswap ? bswap32(value) : value;
106 if (test->isa_base == -1) {
109 writel(test->isa_base + addr, value);
114 static void test_endianness(gconstpointer data)
116 const TestCase *test = data;
119 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
121 test->superio ? " -device " : "",
122 test->superio ?: "");
124 isa_outl(test, 0xe0, 0x87654321);
125 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
126 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
127 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
128 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
129 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
130 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
131 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
133 isa_outw(test, 0xe2, 0x8866);
134 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
135 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
136 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
137 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
138 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
139 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
140 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
142 isa_outw(test, 0xe0, 0x4422);
143 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
144 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
145 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
146 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
147 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
148 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
149 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
151 isa_outb(test, 0xe3, 0x87);
152 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
153 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
154 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
155 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
156 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
157 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
159 isa_outb(test, 0xe2, 0x65);
160 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
161 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
162 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
163 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
164 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
165 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
166 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
168 isa_outb(test, 0xe1, 0x43);
169 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
170 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
171 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
172 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
173 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
174 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
175 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
177 isa_outb(test, 0xe0, 0x21);
178 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
179 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
180 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
181 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
182 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
183 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
184 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
185 qtest_quit(global_qtest);
189 static void test_endianness_split(gconstpointer data)
191 const TestCase *test = data;
194 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
196 test->superio ? " -device " : "",
197 test->superio ?: "");
199 isa_outl(test, 0xe8, 0x87654321);
200 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
201 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
202 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
204 isa_outw(test, 0xea, 0x8866);
205 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
206 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
207 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
209 isa_outw(test, 0xe8, 0x4422);
210 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
211 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
212 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
214 isa_outb(test, 0xeb, 0x87);
215 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
216 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
218 isa_outb(test, 0xea, 0x65);
219 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
220 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
221 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
223 isa_outb(test, 0xe9, 0x43);
224 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
225 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
226 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
228 isa_outb(test, 0xe8, 0x21);
229 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
230 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
231 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
232 qtest_quit(global_qtest);
236 static void test_endianness_combine(gconstpointer data)
238 const TestCase *test = data;
241 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
243 test->superio ? " -device " : "",
244 test->superio ?: "");
246 isa_outl(test, 0xe0, 0x87654321);
247 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
248 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
249 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
251 isa_outw(test, 0xe2, 0x8866);
252 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664321);
253 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
254 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
256 isa_outw(test, 0xe0, 0x4422);
257 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664422);
258 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
259 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
261 isa_outb(test, 0xe3, 0x87);
262 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87664422);
263 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8766);
265 isa_outb(test, 0xe2, 0x65);
266 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654422);
267 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
268 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
270 isa_outb(test, 0xe1, 0x43);
271 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654322);
272 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
273 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4322);
275 isa_outb(test, 0xe0, 0x21);
276 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
277 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
278 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
279 qtest_quit(global_qtest);
283 int main(int argc, char **argv)
285 const char *arch = qtest_get_arch();
289 g_test_init(&argc, &argv, NULL);
291 for (i = 0; test_cases[i].arch; i++) {
293 if (strcmp(test_cases[i].arch, arch) != 0) {
296 path = g_strdup_printf("endianness/%s",
297 test_cases[i].machine);
298 qtest_add_data_func(path, &test_cases[i], test_endianness);
300 path = g_strdup_printf("endianness/split/%s",
301 test_cases[i].machine);
302 qtest_add_data_func(path, &test_cases[i], test_endianness_split);
304 path = g_strdup_printf("endianness/combine/%s",
305 test_cases[i].machine);
306 qtest_add_data_func(path, &test_cases[i], test_endianness_combine);