blob: 09ecb531f118690859bb772ef3e4629752adbf01 [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
Paolo Bonzinia2ce7db2020-08-04 20:00:40 +020016#include "libqos/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", "malta", 0x10000000, .bswap = true },
31 { "mips64", "magnum", 0x90000000, .bswap = true },
32 { "mips64", "pica61", 0x90000000, .bswap = true },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020033 { "mips64", "malta", 0x10000000, .bswap = true },
Philippe Mathieu-Daudéc3a09ff2020-04-26 12:16:37 +020034 { "mips64el", "fuloong2e", 0x1fd00000 },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020035 { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" },
Thomas Huthb2ce76a2020-01-14 12:46:17 +010036 { "ppc", "40p", 0x80000000, .bswap = true },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020037 { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
38 { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" },
David Gibson357d1e32016-10-16 12:04:15 +110039 { "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" },
40 { "ppc64", "pseries-2.7", 0x10080000000ULL,
Stefan Hajnoczi5cb6be22013-11-05 17:42:48 +010041 .bswap = true, .superio = "i82378" },
Paolo Bonzini8fefa312013-07-22 15:54:34 +020042 { "sh4", "r2d", 0xfe240000, .superio = "i82378" },
43 { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },
44 { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true },
45 { "x86_64", "pc", -1 },
46 {}
47};
48
Thomas Huthfdba0d02019-01-03 12:09:50 +010049static uint8_t isa_inb(QTestState *qts, const TestCase *test, uint16_t addr)
Paolo Bonzini8fefa312013-07-22 15:54:34 +020050{
51 uint8_t value;
52 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +010053 value = qtest_inb(qts, addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020054 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +010055 value = qtest_readb(qts, test->isa_base + addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020056 }
57 return value;
58}
59
Thomas Huthfdba0d02019-01-03 12:09:50 +010060static uint16_t isa_inw(QTestState *qts, const TestCase *test, uint16_t addr)
Paolo Bonzini8fefa312013-07-22 15:54:34 +020061{
62 uint16_t value;
63 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +010064 value = qtest_inw(qts, addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020065 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +010066 value = qtest_readw(qts, test->isa_base + addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020067 }
68 return test->bswap ? bswap16(value) : value;
69}
70
Thomas Huthfdba0d02019-01-03 12:09:50 +010071static uint32_t isa_inl(QTestState *qts, const TestCase *test, uint16_t addr)
Paolo Bonzini8fefa312013-07-22 15:54:34 +020072{
73 uint32_t value;
74 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +010075 value = qtest_inl(qts, addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020076 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +010077 value = qtest_readl(qts, test->isa_base + addr);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020078 }
79 return test->bswap ? bswap32(value) : value;
80}
81
Thomas Huthfdba0d02019-01-03 12:09:50 +010082static void isa_outb(QTestState *qts, const TestCase *test, uint16_t addr,
83 uint8_t value)
Paolo Bonzini8fefa312013-07-22 15:54:34 +020084{
85 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +010086 qtest_outb(qts, addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020087 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +010088 qtest_writeb(qts, test->isa_base + addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020089 }
90}
91
Thomas Huthfdba0d02019-01-03 12:09:50 +010092static void isa_outw(QTestState *qts, const TestCase *test, uint16_t addr,
93 uint16_t value)
Paolo Bonzini8fefa312013-07-22 15:54:34 +020094{
95 value = test->bswap ? bswap16(value) : value;
96 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +010097 qtest_outw(qts, addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +020098 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +010099 qtest_writew(qts, test->isa_base + addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200100 }
101}
102
Thomas Huthfdba0d02019-01-03 12:09:50 +0100103static void isa_outl(QTestState *qts, const TestCase *test, uint16_t addr,
104 uint32_t value)
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200105{
106 value = test->bswap ? bswap32(value) : value;
107 if (test->isa_base == -1) {
Thomas Huthfdba0d02019-01-03 12:09:50 +0100108 qtest_outl(qts, addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200109 } else {
Thomas Huthfdba0d02019-01-03 12:09:50 +0100110 qtest_writel(qts, test->isa_base + addr, value);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200111 }
112}
113
114
115static void test_endianness(gconstpointer data)
116{
117 const TestCase *test = data;
Thomas Huthfdba0d02019-01-03 12:09:50 +0100118 QTestState *qts;
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200119
Thomas Huthfdba0d02019-01-03 12:09:50 +0100120 qts = qtest_initf("-M %s%s%s -device pc-testdev", test->machine,
121 test->superio ? " -device " : "",
122 test->superio ?: "");
123 isa_outl(qts, test, 0xe0, 0x87654321);
124 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654321);
125 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
126 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
127 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x87);
128 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x65);
129 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x43);
130 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x21);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200131
Thomas Huthfdba0d02019-01-03 12:09:50 +0100132 isa_outw(qts, test, 0xe2, 0x8866);
133 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x88664321);
134 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8866);
135 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
136 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x88);
137 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x66);
138 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x43);
139 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x21);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200140
Thomas Huthfdba0d02019-01-03 12:09:50 +0100141 isa_outw(qts, test, 0xe0, 0x4422);
142 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x88664422);
143 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8866);
144 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4422);
145 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x88);
146 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x66);
147 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x44);
148 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x22);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200149
Thomas Huthfdba0d02019-01-03 12:09:50 +0100150 isa_outb(qts, test, 0xe3, 0x87);
151 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87664422);
152 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8766);
153 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x87);
154 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x66);
155 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x44);
156 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x22);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200157
Thomas Huthfdba0d02019-01-03 12:09:50 +0100158 isa_outb(qts, test, 0xe2, 0x65);
159 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654422);
160 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
161 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4422);
162 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x87);
163 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x65);
164 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x44);
165 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x22);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200166
Thomas Huthfdba0d02019-01-03 12:09:50 +0100167 isa_outb(qts, test, 0xe1, 0x43);
168 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654322);
169 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
170 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4322);
171 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x87);
172 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x65);
173 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x43);
174 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x22);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200175
Thomas Huthfdba0d02019-01-03 12:09:50 +0100176 isa_outb(qts, test, 0xe0, 0x21);
177 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654321);
178 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
179 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
180 g_assert_cmphex(isa_inb(qts, test, 0xe3), ==, 0x87);
181 g_assert_cmphex(isa_inb(qts, test, 0xe2), ==, 0x65);
182 g_assert_cmphex(isa_inb(qts, test, 0xe1), ==, 0x43);
183 g_assert_cmphex(isa_inb(qts, test, 0xe0), ==, 0x21);
184 qtest_quit(qts);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200185}
186
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200187static void test_endianness_split(gconstpointer data)
188{
189 const TestCase *test = data;
Thomas Huthfdba0d02019-01-03 12:09:50 +0100190 QTestState *qts;
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200191
Thomas Huthfdba0d02019-01-03 12:09:50 +0100192 qts = qtest_initf("-M %s%s%s -device pc-testdev", test->machine,
193 test->superio ? " -device " : "",
194 test->superio ?: "");
195 isa_outl(qts, test, 0xe8, 0x87654321);
196 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654321);
197 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
198 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200199
Thomas Huthfdba0d02019-01-03 12:09:50 +0100200 isa_outw(qts, test, 0xea, 0x8866);
201 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x88664321);
202 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8866);
203 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200204
Thomas Huthfdba0d02019-01-03 12:09:50 +0100205 isa_outw(qts, test, 0xe8, 0x4422);
206 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x88664422);
207 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8866);
208 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4422);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200209
Thomas Huthfdba0d02019-01-03 12:09:50 +0100210 isa_outb(qts, test, 0xeb, 0x87);
211 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87664422);
212 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8766);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200213
Thomas Huthfdba0d02019-01-03 12:09:50 +0100214 isa_outb(qts, test, 0xea, 0x65);
215 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654422);
216 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
217 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4422);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200218
Thomas Huthfdba0d02019-01-03 12:09:50 +0100219 isa_outb(qts, test, 0xe9, 0x43);
220 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654322);
221 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
222 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4322);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200223
Thomas Huthfdba0d02019-01-03 12:09:50 +0100224 isa_outb(qts, test, 0xe8, 0x21);
225 g_assert_cmphex(isa_inl(qts, test, 0xe0), ==, 0x87654321);
226 g_assert_cmphex(isa_inw(qts, test, 0xe2), ==, 0x8765);
227 g_assert_cmphex(isa_inw(qts, test, 0xe0), ==, 0x4321);
228 qtest_quit(qts);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200229}
230
231static void test_endianness_combine(gconstpointer data)
232{
233 const TestCase *test = data;
Thomas Huthfdba0d02019-01-03 12:09:50 +0100234 QTestState *qts;
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200235
Thomas Huthfdba0d02019-01-03 12:09:50 +0100236 qts = qtest_initf("-M %s%s%s -device pc-testdev", test->machine,
237 test->superio ? " -device " : "",
238 test->superio ?: "");
239 isa_outl(qts, test, 0xe0, 0x87654321);
240 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x87654321);
241 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8765);
242 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4321);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200243
Thomas Huthfdba0d02019-01-03 12:09:50 +0100244 isa_outw(qts, test, 0xe2, 0x8866);
245 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x88664321);
246 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8866);
247 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4321);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200248
Thomas Huthfdba0d02019-01-03 12:09:50 +0100249 isa_outw(qts, test, 0xe0, 0x4422);
250 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x88664422);
251 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8866);
252 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4422);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200253
Thomas Huthfdba0d02019-01-03 12:09:50 +0100254 isa_outb(qts, test, 0xe3, 0x87);
255 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x87664422);
256 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8766);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200257
Thomas Huthfdba0d02019-01-03 12:09:50 +0100258 isa_outb(qts, test, 0xe2, 0x65);
259 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x87654422);
260 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8765);
261 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4422);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200262
Thomas Huthfdba0d02019-01-03 12:09:50 +0100263 isa_outb(qts, test, 0xe1, 0x43);
264 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x87654322);
265 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8765);
266 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4322);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200267
Thomas Huthfdba0d02019-01-03 12:09:50 +0100268 isa_outb(qts, test, 0xe0, 0x21);
269 g_assert_cmphex(isa_inl(qts, test, 0xe8), ==, 0x87654321);
270 g_assert_cmphex(isa_inw(qts, test, 0xea), ==, 0x8765);
271 g_assert_cmphex(isa_inw(qts, test, 0xe8), ==, 0x4321);
272 qtest_quit(qts);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200273}
274
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200275int main(int argc, char **argv)
276{
277 const char *arch = qtest_get_arch();
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200278 int i;
279
280 g_test_init(&argc, &argv, NULL);
281
282 for (i = 0; test_cases[i].arch; i++) {
283 gchar *path;
284 if (strcmp(test_cases[i].arch, arch) != 0) {
285 continue;
286 }
Andreas Färber53f77e42015-03-25 18:40:15 +0100287 path = g_strdup_printf("endianness/%s",
288 test_cases[i].machine);
289 qtest_add_data_func(path, &test_cases[i], test_endianness);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400290 g_free(path);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200291
Andreas Färber53f77e42015-03-25 18:40:15 +0100292 path = g_strdup_printf("endianness/split/%s",
293 test_cases[i].machine);
294 qtest_add_data_func(path, &test_cases[i], test_endianness_split);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400295 g_free(path);
Paolo Bonzinid2f5ea92013-07-22 15:54:38 +0200296
Andreas Färber53f77e42015-03-25 18:40:15 +0100297 path = g_strdup_printf("endianness/combine/%s",
298 test_cases[i].machine);
299 qtest_add_data_func(path, &test_cases[i], test_endianness_combine);
Marc-André Lureauf3f8e812017-01-27 13:01:39 +0400300 g_free(path);
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200301 }
302
Eduardo Habkost9be38592016-06-13 18:57:58 -0300303 return g_test_run();
Paolo Bonzini8fefa312013-07-22 15:54:34 +0200304}