blob: 48680cd1315f67574eafa790cf336c3d0734840d [file] [log] [blame]
Paolo Bonzini8fefa312013-07-22 15:54:34 +02001/*
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 */
Paolo Bonzini8fefa312013-07-22 15:54:34 +020013
Peter Maydell681c28a2016-02-08 18:08:51 +000014#include "qemu/osdep.h"
Paolo Bonzini8fefa312013-07-22 15:54:34 +020015
Stefan Hajnoczi91f32b02014-02-08 11:41:07 +010016#include "libqtest.h"
Paolo Bonzini8fefa312013-07-22 15:54:34 +020017#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 },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020030 { "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" },
David Gibson357d1e32016-10-16 12:04:15 +110041 { "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" },
42 { "ppc64", "pseries-2.7", 0x10080000000ULL,
Stefan Hajnoczi5cb6be22013-11-05 17:42:48 +010043 .bswap = true, .superio = "i82378" },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020044 { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
45 { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
46 { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
47 { "x86_64", "pc", -1 },
48 {}
49};
50
51static uint8_t isa_inb(const TestCase *test, uint16_t addr)
52{
53 uint8_t value;
54 if (test->isa_base == -1) {
55 value = inb(addr);
56 } else {
57 value = readb(test->isa_base + addr);
58 }
59 return value;
60}
61
62static uint16_t isa_inw(const TestCase *test, uint16_t addr)
63{
64 uint16_t value;
65 if (test->isa_base == -1) {
66 value = inw(addr);
67 } else {
68 value = readw(test->isa_base + addr);
69 }
70 return test->bswap ? bswap16(value) : value;
71}
72
73static uint32_t isa_inl(const TestCase *test, uint16_t addr)
74{
75 uint32_t value;
76 if (test->isa_base == -1) {
77 value = inl(addr);
78 } else {
79 value = readl(test->isa_base + addr);
80 }
81 return test->bswap ? bswap32(value) : value;
82}
83
84static void isa_outb(const TestCase *test, uint16_t addr, uint8_t value)
85{
86 if (test->isa_base == -1) {
87 outb(addr, value);
88 } else {
89 writeb(test->isa_base + addr, value);
90 }
91}
92
93static void isa_outw(const TestCase *test, uint16_t addr, uint16_t value)
94{
95 value = test->bswap ? bswap16(value) : value;
96 if (test->isa_base == -1) {
97 outw(addr, value);
98 } else {
99 writew(test->isa_base + addr, value);
100 }
101}
102
103static void isa_outl(const TestCase *test, uint16_t addr, uint32_t value)
104{
105 value = test->bswap ? bswap32(value) : value;
106 if (test->isa_base == -1) {
107 outl(addr, value);
108 } else {
109 writel(test->isa_base + addr, value);
110 }
111}
112
113
114static void test_endianness(gconstpointer data)
115{
116 const TestCase *test = data;
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200117
Markus Armbruster88b988c2018-08-06 08:53:43 +0200118 global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
119 test->machine,
120 test->superio ? " -device " : "",
121 test->superio ?: "");
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200122 isa_outl(test, 0xe0, 0x87654321);
123 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
124 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
125 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
126 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
127 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
128 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
129 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
130
131 isa_outw(test, 0xe2, 0x8866);
132 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
133 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
134 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
135 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
136 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
137 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
138 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
139
140 isa_outw(test, 0xe0, 0x4422);
141 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
142 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
143 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
144 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88);
145 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
146 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
147 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
148
149 isa_outb(test, 0xe3, 0x87);
150 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
151 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
152 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
153 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66);
154 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
155 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
156
157 isa_outb(test, 0xe2, 0x65);
158 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
159 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
160 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
161 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
162 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
163 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44);
164 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
165
166 isa_outb(test, 0xe1, 0x43);
167 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
168 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
169 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
170 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
171 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
172 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
173 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22);
174
175 isa_outb(test, 0xe0, 0x21);
176 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
177 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
178 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
179 g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87);
180 g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65);
181 g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43);
182 g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21);
183 qtest_quit(global_qtest);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200184}
185
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200186static void test_endianness_split(gconstpointer data)
187{
188 const TestCase *test = data;
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200189
Markus Armbruster88b988c2018-08-06 08:53:43 +0200190 global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
191 test->machine,
192 test->superio ? " -device " : "",
193 test->superio ?: "");
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200194 isa_outl(test, 0xe8, 0x87654321);
195 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
196 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
197 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
198
199 isa_outw(test, 0xea, 0x8866);
200 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321);
201 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
202 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
203
204 isa_outw(test, 0xe8, 0x4422);
205 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422);
206 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866);
207 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
208
209 isa_outb(test, 0xeb, 0x87);
210 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422);
211 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766);
212
213 isa_outb(test, 0xea, 0x65);
214 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422);
215 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
216 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422);
217
218 isa_outb(test, 0xe9, 0x43);
219 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322);
220 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
221 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322);
222
223 isa_outb(test, 0xe8, 0x21);
224 g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
225 g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
226 g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321);
227 qtest_quit(global_qtest);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200228}
229
230static void test_endianness_combine(gconstpointer data)
231{
232 const TestCase *test = data;
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200233
Markus Armbruster88b988c2018-08-06 08:53:43 +0200234 global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
235 test->machine,
236 test->superio ? " -device " : "",
237 test->superio ?: "");
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200238 isa_outl(test, 0xe0, 0x87654321);
239 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
240 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
241 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
242
243 isa_outw(test, 0xe2, 0x8866);
244 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664321);
245 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
246 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
247
248 isa_outw(test, 0xe0, 0x4422);
249 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664422);
250 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866);
251 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
252
253 isa_outb(test, 0xe3, 0x87);
254 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87664422);
255 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8766);
256
257 isa_outb(test, 0xe2, 0x65);
258 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654422);
259 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
260 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422);
261
262 isa_outb(test, 0xe1, 0x43);
263 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654322);
264 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
265 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4322);
266
267 isa_outb(test, 0xe0, 0x21);
268 g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
269 g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
270 g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321);
271 qtest_quit(global_qtest);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200272}
273
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200274int main(int argc, char **argv)
275{
276 const char *arch = qtest_get_arch();
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200277 int i;
278
279 g_test_init(&argc, &argv, NULL);
280
281 for (i = 0; test_cases[i].arch; i++) {
282 gchar *path;
283 if (strcmp(test_cases[i].arch, arch) != 0) {
284 continue;
285 }
Andreas Färber53f77e42015-03-25 18:40:15 +0100286 path = g_strdup_printf("endianness/%s",
287 test_cases[i].machine);
288 qtest_add_data_func(path, &test_cases[i], test_endianness);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400289 g_free(path);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200290
Andreas Färber53f77e42015-03-25 18:40:15 +0100291 path = g_strdup_printf("endianness/split/%s",
292 test_cases[i].machine);
293 qtest_add_data_func(path, &test_cases[i], test_endianness_split);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400294 g_free(path);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200295
Andreas Färber53f77e42015-03-25 18:40:15 +0100296 path = g_strdup_printf("endianness/combine/%s",
297 test_cases[i].machine);
298 qtest_add_data_func(path, &test_cases[i], test_endianness_combine);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400299 g_free(path);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200300 }
301
Eduardo Habkost9be38592016-06-13 18:57:58 -0300302 return g_test_run();
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200303}