qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

endianness-test.c (11302B)


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