]> git.ipfire.org Git - thirdparty/qemu.git/blame - tests/endianness-test.c
qdev: Free property names after registering gpio aliases
[thirdparty/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
PB
13
14#include <glib.h>
15#include <stdio.h>
16#include <string.h>
17#include <stdlib.h>
18#include <unistd.h>
19
91f32b0c 20#include "libqtest.h"
8fefa31b
PB
21#include "qemu/bswap.h"
22
23typedef struct TestCase TestCase;
24struct TestCase {
25 const char *arch;
26 const char *machine;
27 uint64_t isa_base;
28 bool bswap;
29 const char *superio;
30};
31
32static const TestCase test_cases[] = {
33 { "i386", "pc", -1 },
8fefa31b
PB
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" },
5cb6be2c
SH
45 { "ppc64", "pseries", 0x10080000000ULL,
46 .bswap = true, .superio = "i82378" },
8fefa31b
PB
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
54static 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
65static 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
76static 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
87static 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
96static 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
106static 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
117static void test_endianness(gconstpointer data)
118{
119 const TestCase *test = data;
120 char *args;
121
2ad645d2 122 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
8fefa31b
PB
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
d2f5ea97
PB
192static void test_endianness_split(gconstpointer data)
193{
194 const TestCase *test = data;
195 char *args;
196
2ad645d2 197 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
d2f5ea97
PB
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
239static void test_endianness_combine(gconstpointer data)
240{
241 const TestCase *test = data;
242 char *args;
243
2ad645d2 244 args = g_strdup_printf("-M %s%s%s -device pc-testdev",
d2f5ea97
PB
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
8fefa31b
PB
286int 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("/%s/endianness/%s",
300 arch, test_cases[i].machine);
301 g_test_add_data_func(path, &test_cases[i], test_endianness);
d2f5ea97
PB
302
303 path = g_strdup_printf("/%s/endianness/split/%s",
304 arch, test_cases[i].machine);
305 g_test_add_data_func(path, &test_cases[i], test_endianness_split);
306
307 path = g_strdup_printf("/%s/endianness/combine/%s",
308 arch, test_cases[i].machine);
309 g_test_add_data_func(path, &test_cases[i], test_endianness_combine);
8fefa31b
PB
310 }
311
312 ret = g_test_run();
313
314 return ret;
315}