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