diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile | 23 | ||||
-rw-r--r-- | tests/boot-order-test.c | 209 | ||||
-rw-r--r-- | tests/endianness-test.c | 316 | ||||
-rw-r--r-- | tests/fdc-test.c | 2 | ||||
-rw-r--r-- | tests/fw_cfg-test.c | 2 | ||||
-rw-r--r-- | tests/hd-geo-test.c | 8 | ||||
-rw-r--r-- | tests/ide-test.c | 2 | ||||
-rw-r--r-- | tests/libqos/fw_cfg-pc.c | 40 | ||||
-rw-r--r-- | tests/libqos/fw_cfg-pc.h | 20 | ||||
-rw-r--r-- | tests/libqos/fw_cfg.c | 55 | ||||
-rw-r--r-- | tests/libqos/fw_cfg.h | 9 | ||||
-rw-r--r-- | tests/libqos/malloc-pc.c | 2 | ||||
-rw-r--r-- | tests/libqtest.c | 4 | ||||
-rw-r--r-- | tests/libqtest.h | 12 | ||||
-rw-r--r-- | tests/test-bitops.c | 75 |
15 files changed, 708 insertions, 71 deletions
diff --git a/tests/Makefile b/tests/Makefile index 279d5f8307..cdbb79e111 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -47,28 +47,41 @@ gcov-files-test-mul64-y = util/host-utils.c check-unit-y += tests/test-int128$(EXESUF) # all code tested by test-int128 is inside int128.h gcov-files-test-int128-y = +check-unit-y += tests/test-bitops$(EXESUF) check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh # All QTests for now are POSIX-only, but the dependencies are # really in libqtest, not in the testcases themselves. -check-qtest-i386-y = tests/fdc-test$(EXESUF) +check-qtest-i386-y = tests/endianness-test$(EXESUF) +check-qtest-i386-y += tests/fdc-test$(EXESUF) gcov-files-i386-y = hw/fdc.c check-qtest-i386-y += tests/ide-test$(EXESUF) check-qtest-i386-y += tests/hd-geo-test$(EXESUF) gcov-files-i386-y += hw/hd-geometry.c +check-qtest-i386-y += tests/boot-order-test$(EXESUF) check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y)) +check-qtest-mips-y = tests/endianness-test$(EXESUF) +check-qtest-mips64-y = tests/endianness-test$(EXESUF) +check-qtest-mips64el-y = tests/endianness-test$(EXESUF) +check-qtest-ppc-y = tests/endianness-test$(EXESUF) +check-qtest-ppc64-y = tests/endianness-test$(EXESUF) +check-qtest-sh4-y = tests/endianness-test$(EXESUF) +check-qtest-sh4eb-y = tests/endianness-test$(EXESUF) +check-qtest-sparc64-y = tests/endianness-test$(EXESUF) #check-qtest-sparc-y = tests/m48t59-test$(EXESUF) -#check-qtest-sparc64-y = tests/m48t59-test$(EXESUF) +#check-qtest-sparc64-y += tests/m48t59-test$(EXESUF) gcov-files-sparc-y += hw/m48t59.c gcov-files-sparc64-y += hw/m48t59.c check-qtest-arm-y = tests/tmp105-test$(EXESUF) gcov-files-arm-y += hw/tmp105.c +check-qtest-ppc-y += tests/boot-order-test$(EXESUF) +check-qtest-ppc64-y += tests/boot-order-test$(EXESUF) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h @@ -122,18 +135,21 @@ tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marsh tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a +tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o libqos-obj-y += tests/libqos/i2c.o -libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o tests/libqos/fw_cfg-pc.o +libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o libqos-pc-obj-y += tests/libqos/malloc-pc.o libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o tests/rtc-test$(EXESUF): tests/rtc-test.o tests/m48t59-test$(EXESUF): tests/m48t59-test.o +tests/endianness-test$(EXESUF): tests/endianness-test.o tests/fdc-test$(EXESUF): tests/fdc-test.o tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y) tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o +tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y) tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y) tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y) tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y) @@ -226,3 +242,4 @@ check-block: $(patsubst %,check-%, $(check-block-y)) check: check-unit check-qtest -include $(wildcard tests/*.d) +-include $(wildcard tests/libqos/*.d) diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c new file mode 100644 index 0000000000..4b233d0b24 --- /dev/null +++ b/tests/boot-order-test.c @@ -0,0 +1,209 @@ +/* + * Boot order test cases. + * + * Copyright (c) 2013 Red Hat Inc. + * + * Authors: + * Markus Armbruster <armbru@redhat.com>, + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include <string.h> +#include <glib.h> +#include "libqos/fw_cfg.h" +#include "libqtest.h" + +#define NO_QEMU_PROTOS +#include "hw/nvram/fw_cfg.h" +#undef NO_QEMU_PROTOS + +typedef struct { + const char *args; + uint64_t expected_boot; + uint64_t expected_reboot; +} boot_order_test; + +static void test_a_boot_order(const char *machine, + const char *test_args, + uint64_t (*read_boot_order)(void), + uint64_t expected_boot, + uint64_t expected_reboot) +{ + char *args; + uint64_t actual; + + args = g_strdup_printf("-nodefaults -display none%s%s %s", + machine ? " -M " : "", + machine ?: "", + test_args); + qtest_start(args); + actual = read_boot_order(); + g_assert_cmphex(actual, ==, expected_boot); + qmp("{ 'execute': 'system_reset' }"); + /* + * system_reset only requests reset. We get a RESET event after + * the actual reset completes. Need to wait for that. + */ + qmp(""); /* HACK: wait for event */ + actual = read_boot_order(); + g_assert_cmphex(actual, ==, expected_reboot); + qtest_quit(global_qtest); + g_free(args); +} + +static void test_boot_orders(const char *machine, + uint64_t (*read_boot_order)(void), + const boot_order_test *tests) +{ + int i; + + for (i = 0; tests[i].args; i++) { + test_a_boot_order(machine, tests[i].args, + read_boot_order, + tests[i].expected_boot, + tests[i].expected_reboot); + } +} + +static uint8_t read_mc146818(uint16_t port, uint8_t reg) +{ + outb(port, reg); + return inb(port + 1); +} + +static uint64_t read_boot_order_pc(void) +{ + uint8_t b1 = read_mc146818(0x70, 0x38); + uint8_t b2 = read_mc146818(0x70, 0x3d); + + return b1 | (b2 << 8); +} + +static const boot_order_test test_cases_pc[] = { + { "", + 0x1230, 0x1230 }, + { "-no-fd-bootchk", + 0x1231, 0x1231 }, + { "-boot c", + 0x0200, 0x0200 }, + { "-boot nda", + 0x3410, 0x3410 }, + { "-boot order=", + 0, 0 }, + { "-boot order= -boot order=c", + 0x0200, 0x0200 }, + { "-boot once=a", + 0x0100, 0x1230 }, + { "-boot once=a -no-fd-bootchk", + 0x0101, 0x1231 }, + { "-boot once=a,order=c", + 0x0100, 0x0200 }, + { "-boot once=d -boot order=nda", + 0x0300, 0x3410 }, + { "-boot once=a -boot once=b -boot once=c", + 0x0200, 0x1230 }, + {} +}; + +static void test_pc_boot_order(void) +{ + test_boot_orders(NULL, read_boot_order_pc, test_cases_pc); +} + +static uint8_t read_m48t59(uint64_t addr, uint16_t reg) +{ + writeb(addr, reg & 0xff); + writeb(addr + 1, reg >> 8); + return readb(addr + 3); +} + +static uint64_t read_boot_order_prep(void) +{ + return read_m48t59(0x80000000 + 0x74, 0x34); +} + +static const boot_order_test test_cases_prep[] = { + { "", 'c', 'c' }, + { "-boot c", 'c', 'c' }, + { "-boot d", 'd', 'd' }, + {} +}; + +static void test_prep_boot_order(void) +{ + test_boot_orders("prep", read_boot_order_prep, test_cases_prep); +} + +static uint64_t read_boot_order_pmac(void) +{ + QFWCFG *fw_cfg = mm_fw_cfg_init(0xf0000510); + + return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE); +} + +static const boot_order_test test_cases_fw_cfg[] = { + { "", 'c', 'c' }, + { "-boot c", 'c', 'c' }, + { "-boot d", 'd', 'd' }, + { "-boot once=d,order=c", 'd', 'c' }, + {} +}; + +static void test_pmac_oldworld_boot_order(void) +{ + test_boot_orders("g3beige", read_boot_order_pmac, test_cases_fw_cfg); +} + +static void test_pmac_newworld_boot_order(void) +{ + test_boot_orders("mac99", read_boot_order_pmac, test_cases_fw_cfg); +} + +static uint64_t read_boot_order_sun4m(void) +{ + QFWCFG *fw_cfg = mm_fw_cfg_init(0xd00000510ULL); + + return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE); +} + +static void test_sun4m_boot_order(void) +{ + test_boot_orders("SS-5", read_boot_order_sun4m, test_cases_fw_cfg); +} + +static uint64_t read_boot_order_sun4u(void) +{ + QFWCFG *fw_cfg = io_fw_cfg_init(0x510); + + return qfw_cfg_get_u16(fw_cfg, FW_CFG_BOOT_DEVICE); +} + +static void test_sun4u_boot_order(void) +{ + test_boot_orders("sun4u", read_boot_order_sun4u, test_cases_fw_cfg); +} + +int main(int argc, char *argv[]) +{ + const char *arch = qtest_get_arch(); + + g_test_init(&argc, &argv, NULL); + + if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { + qtest_add_func("boot-order/pc", test_pc_boot_order); + } else if (strcmp(arch, "ppc") == 0 || strcmp(arch, "ppc64") == 0) { + qtest_add_func("boot-order/prep", test_prep_boot_order); + qtest_add_func("boot-order/pmac_oldworld", + test_pmac_oldworld_boot_order); + qtest_add_func("boot-order/pmac_newworld", + test_pmac_newworld_boot_order); + } else if (strcmp(arch, "sparc") == 0) { + qtest_add_func("boot-order/sun4m", test_sun4m_boot_order); + } else if (strcmp(arch, "sparc64") == 0) { + qtest_add_func("boot-order/sun4u", test_sun4u_boot_order); + } + + return g_test_run(); +} diff --git a/tests/endianness-test.c b/tests/endianness-test.c new file mode 100644 index 0000000000..feb32a8503 --- /dev/null +++ b/tests/endianness-test.c @@ -0,0 +1,316 @@ +/* + * QTest testcase for ISA endianness + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Paolo Bonzini <pbonzini@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#include "libqtest.h" + +#include <glib.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include "qemu/bswap.h" + +typedef struct TestCase TestCase; +struct TestCase { + const char *arch; + const char *machine; + uint64_t isa_base; + bool bswap; + const char *superio; +}; + +static const TestCase test_cases[] = { + { "i386", "pc", -1 }, + { "mips", "magnum", 0x90000000, .bswap = true }, + { "mips", "pica61", 0x90000000, .bswap = true }, + { "mips", "mips", 0x14000000, .bswap = true }, + { "mips", "malta", 0x10000000, .bswap = true }, + { "mips64", "magnum", 0x90000000, .bswap = true }, + { "mips64", "pica61", 0x90000000, .bswap = true }, + { "mips64", "mips", 0x14000000, .bswap = true }, + { "mips64", "malta", 0x10000000, .bswap = true }, + { "mips64el", "fulong2e", 0x1fd00000 }, + { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" }, + { "ppc", "prep", 0x80000000, .bswap = true }, + { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" }, + { "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" }, + { "ppc64", "pseries", 0x10080000000, .bswap = true, .superio = "i82378" }, + { "sh4", "r2d", 0xfe240000, .superio = "i82378" }, + { "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" }, + { "sparc64", "sun4u", 0x1fe02000000LL, .bswap = true }, + { "x86_64", "pc", -1 }, + {} +}; + +static uint8_t isa_inb(const TestCase *test, uint16_t addr) +{ + uint8_t value; + if (test->isa_base == -1) { + value = inb(addr); + } else { + value = readb(test->isa_base + addr); + } + return value; +} + +static uint16_t isa_inw(const TestCase *test, uint16_t addr) +{ + uint16_t value; + if (test->isa_base == -1) { + value = inw(addr); + } else { + value = readw(test->isa_base + addr); + } + return test->bswap ? bswap16(value) : value; +} + +static uint32_t isa_inl(const TestCase *test, uint16_t addr) +{ + uint32_t value; + if (test->isa_base == -1) { + value = inl(addr); + } else { + value = readl(test->isa_base + addr); + } + return test->bswap ? bswap32(value) : value; +} + +static void isa_outb(const TestCase *test, uint16_t addr, uint8_t value) +{ + if (test->isa_base == -1) { + outb(addr, value); + } else { + writeb(test->isa_base + addr, value); + } +} + +static void isa_outw(const TestCase *test, uint16_t addr, uint16_t value) +{ + value = test->bswap ? bswap16(value) : value; + if (test->isa_base == -1) { + outw(addr, value); + } else { + writew(test->isa_base + addr, value); + } +} + +static void isa_outl(const TestCase *test, uint16_t addr, uint32_t value) +{ + value = test->bswap ? bswap32(value) : value; + if (test->isa_base == -1) { + outl(addr, value); + } else { + writel(test->isa_base + addr, value); + } +} + + +static void test_endianness(gconstpointer data) +{ + const TestCase *test = data; + char *args; + + args = g_strdup_printf("-display none -M %s%s%s -device pc-testdev", + test->machine, + test->superio ? " -device " : "", + test->superio ?: ""); + qtest_start(args); + isa_outl(test, 0xe0, 0x87654321); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); + + isa_outw(test, 0xe2, 0x8866); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); + + isa_outw(test, 0xe0, 0x4422); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x88); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); + + isa_outb(test, 0xe3, 0x87); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x66); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); + + isa_outb(test, 0xe2, 0x65); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x44); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); + + isa_outb(test, 0xe1, 0x43); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x22); + + isa_outb(test, 0xe0, 0x21); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + g_assert_cmphex(isa_inb(test, 0xe3), ==, 0x87); + g_assert_cmphex(isa_inb(test, 0xe2), ==, 0x65); + g_assert_cmphex(isa_inb(test, 0xe1), ==, 0x43); + g_assert_cmphex(isa_inb(test, 0xe0), ==, 0x21); + qtest_quit(global_qtest); + g_free(args); +} + +static void test_endianness_split(gconstpointer data) +{ + const TestCase *test = data; + char *args; + + args = g_strdup_printf("-display none -M %s%s%s -device pc-testdev", + test->machine, + test->superio ? " -device " : "", + test->superio ?: ""); + qtest_start(args); + isa_outl(test, 0xe8, 0x87654321); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + + isa_outw(test, 0xea, 0x8866); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + + isa_outw(test, 0xe8, 0x4422); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x88664422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); + + isa_outb(test, 0xeb, 0x87); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87664422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8766); + + isa_outb(test, 0xea, 0x65); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654422); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4422); + + isa_outb(test, 0xe9, 0x43); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654322); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4322); + + isa_outb(test, 0xe8, 0x21); + g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe0), ==, 0x4321); + qtest_quit(global_qtest); + g_free(args); +} + +static void test_endianness_combine(gconstpointer data) +{ + const TestCase *test = data; + char *args; + + args = g_strdup_printf("-display none -M %s%s%s -device pc-testdev", + test->machine, + test->superio ? " -device " : "", + test->superio ?: ""); + qtest_start(args); + isa_outl(test, 0xe0, 0x87654321); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321); + + isa_outw(test, 0xe2, 0x8866); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664321); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321); + + isa_outw(test, 0xe0, 0x4422); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x88664422); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8866); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422); + + isa_outb(test, 0xe3, 0x87); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87664422); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8766); + + isa_outb(test, 0xe2, 0x65); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654422); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4422); + + isa_outb(test, 0xe1, 0x43); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654322); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4322); + + isa_outb(test, 0xe0, 0x21); + g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321); + g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765); + g_assert_cmphex(isa_inw(test, 0xe8), ==, 0x4321); + qtest_quit(global_qtest); + g_free(args); +} + +int main(int argc, char **argv) +{ + const char *arch = qtest_get_arch(); + int ret; + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; test_cases[i].arch; i++) { + gchar *path; + if (strcmp(test_cases[i].arch, arch) != 0) { + continue; + } + path = g_strdup_printf("/%s/endianness/%s", + arch, test_cases[i].machine); + g_test_add_data_func(path, &test_cases[i], test_endianness); + + path = g_strdup_printf("/%s/endianness/split/%s", + arch, test_cases[i].machine); + g_test_add_data_func(path, &test_cases[i], test_endianness_split); + + path = g_strdup_printf("/%s/endianness/combine/%s", + arch, test_cases[i].machine); + g_test_add_data_func(path, &test_cases[i], test_endianness_combine); + } + + ret = g_test_run(); + + return ret; +} diff --git a/tests/fdc-test.c b/tests/fdc-test.c index 4b0301da46..fd198dcf8b 100644 --- a/tests/fdc-test.c +++ b/tests/fdc-test.c @@ -556,7 +556,7 @@ int main(int argc, char **argv) ret = g_test_run(); /* Cleanup */ - qtest_quit(global_qtest); + qtest_end(); unlink(test_image); return ret; diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c index c284c4d743..b86e49ab09 100644 --- a/tests/fw_cfg-test.c +++ b/tests/fw_cfg-test.c @@ -14,7 +14,7 @@ #include "libqtest.h" #include "hw/nvram/fw_cfg.h" -#include "libqos/fw_cfg-pc.h" +#include "libqos/fw_cfg.h" #include <string.h> #include <glib.h> diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c index 9a31e8587f..b72042e59d 100644 --- a/tests/hd-geo-test.c +++ b/tests/hd-geo-test.c @@ -244,7 +244,7 @@ static void test_ide_none(void) setup_common(argv, ARRAY_SIZE(argv)); qtest_start(g_strjoinv(" ", argv)); test_cmos(); - qtest_quit(global_qtest); + qtest_end(); } static void test_ide_mbr(bool use_device, MBRcontents mbr) @@ -262,7 +262,7 @@ static void test_ide_mbr(bool use_device, MBRcontents mbr) } qtest_start(g_strjoinv(" ", argv)); test_cmos(); - qtest_quit(global_qtest); + qtest_end(); } /* @@ -334,7 +334,7 @@ static void test_ide_drive_user(const char *dev, bool trans) g_free(opts); qtest_start(g_strjoinv(" ", argv)); test_cmos(); - qtest_quit(global_qtest); + qtest_end(); } /* @@ -387,7 +387,7 @@ static void test_ide_drive_cd_0(void) } qtest_start(g_strjoinv(" ", argv)); test_cmos(); - qtest_quit(global_qtest); + qtest_end(); } int main(int argc, char **argv) diff --git a/tests/ide-test.c b/tests/ide-test.c index 7e2eb9455a..7307f1d336 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -122,7 +122,7 @@ static void ide_test_start(const char *cmdline_fmt, ...) static void ide_test_quit(void) { - qtest_quit(global_qtest); + qtest_end(); } static QPCIDevice *get_pci_device(uint16_t *bmdma_base) diff --git a/tests/libqos/fw_cfg-pc.c b/tests/libqos/fw_cfg-pc.c deleted file mode 100644 index 613604db77..0000000000 --- a/tests/libqos/fw_cfg-pc.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * libqos fw_cfg support for PC - * - * Copyright IBM, Corp. 2012-2013 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#include "libqos/fw_cfg-pc.h" -#include "libqtest.h" -#include <glib.h> - -static void pc_fw_cfg_select(QFWCFG *fw_cfg, uint16_t key) -{ - outw(0x510, key); -} - -static void pc_fw_cfg_read(QFWCFG *fw_cfg, void *data, size_t len) -{ - uint8_t *ptr = data; - int i; - - for (i = 0; i < len; i++) { - ptr[i] = inb(0x511); - } -} - -QFWCFG *pc_fw_cfg_init(void) -{ - QFWCFG *fw_cfg = g_malloc0(sizeof(*fw_cfg)); - - fw_cfg->select = pc_fw_cfg_select; - fw_cfg->read = pc_fw_cfg_read; - - return fw_cfg; -} diff --git a/tests/libqos/fw_cfg-pc.h b/tests/libqos/fw_cfg-pc.h deleted file mode 100644 index 444bd7975a..0000000000 --- a/tests/libqos/fw_cfg-pc.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * libqos fw_cfg support for PC - * - * Copyright IBM, Corp. 2012-2013 - * - * Authors: - * Anthony Liguori <aliguori@us.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef LIBQOS_FW_CFG_PC_H -#define LIBQOS_FW_CFG_PC_H - -#include "libqos/fw_cfg.h" - -QFWCFG *pc_fw_cfg_init(void); - -#endif diff --git a/tests/libqos/fw_cfg.c b/tests/libqos/fw_cfg.c index e386ff7ba7..ef00fedf1a 100644 --- a/tests/libqos/fw_cfg.c +++ b/tests/libqos/fw_cfg.c @@ -2,15 +2,19 @@ * libqos fw_cfg support * * Copyright IBM, Corp. 2012-2013 + * Copyright (C) 2013 Red Hat Inc. * * Authors: * Anthony Liguori <aliguori@us.ibm.com> + * Markus Armbruster <armbru@redhat.com> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ +#include <glib.h> #include "libqos/fw_cfg.h" +#include "libqtest.h" #include "qemu/bswap.h" void qfw_cfg_select(QFWCFG *fw_cfg, uint16_t key) @@ -50,3 +54,54 @@ uint64_t qfw_cfg_get_u64(QFWCFG *fw_cfg, uint16_t key) return le64_to_cpu(value); } +static void mm_fw_cfg_select(QFWCFG *fw_cfg, uint16_t key) +{ + writew(fw_cfg->base, key); +} + +static void mm_fw_cfg_read(QFWCFG *fw_cfg, void *data, size_t len) +{ + uint8_t *ptr = data; + int i; + + for (i = 0; i < len; i++) { + ptr[i] = readb(fw_cfg->base + 2); + } +} + +QFWCFG *mm_fw_cfg_init(uint64_t base) +{ + QFWCFG *fw_cfg = g_malloc0(sizeof(*fw_cfg)); + + fw_cfg->base = base; + fw_cfg->select = mm_fw_cfg_select; + fw_cfg->read = mm_fw_cfg_read; + + return fw_cfg; +} + +static void io_fw_cfg_select(QFWCFG *fw_cfg, uint16_t key) +{ + outw(fw_cfg->base, key); +} + +static void io_fw_cfg_read(QFWCFG *fw_cfg, void *data, size_t len) +{ + uint8_t *ptr = data; + int i; + + for (i = 0; i < len; i++) { + ptr[i] = inb(fw_cfg->base + 1); + } +} + +QFWCFG *io_fw_cfg_init(uint16_t base) +{ + QFWCFG *fw_cfg = g_malloc0(sizeof(*fw_cfg)); + + fw_cfg->base = base; + fw_cfg->select = io_fw_cfg_select; + fw_cfg->read = io_fw_cfg_read; + + return fw_cfg; +} diff --git a/tests/libqos/fw_cfg.h b/tests/libqos/fw_cfg.h index 44fc42ba11..61b1548b4e 100644 --- a/tests/libqos/fw_cfg.h +++ b/tests/libqos/fw_cfg.h @@ -20,6 +20,7 @@ typedef struct QFWCFG QFWCFG; struct QFWCFG { + uint64_t base; void (*select)(QFWCFG *fw_cfg, uint16_t key); void (*read)(QFWCFG *fw_cfg, void *data, size_t len); }; @@ -31,4 +32,12 @@ uint16_t qfw_cfg_get_u16(QFWCFG *fw_cfg, uint16_t key); uint32_t qfw_cfg_get_u32(QFWCFG *fw_cfg, uint16_t key); uint64_t qfw_cfg_get_u64(QFWCFG *fw_cfg, uint16_t key); +QFWCFG *mm_fw_cfg_init(uint64_t base); +QFWCFG *io_fw_cfg_init(uint16_t base); + +static inline QFWCFG *pc_fw_cfg_init(void) +{ + return io_fw_cfg_init(0x510); +} + #endif diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c index adc36c4731..db1496c667 100644 --- a/tests/libqos/malloc-pc.c +++ b/tests/libqos/malloc-pc.c @@ -11,7 +11,7 @@ */ #include "libqos/malloc-pc.h" -#include "libqos/fw_cfg-pc.h" +#include "libqos/fw_cfg.h" #define NO_QEMU_PROTOS #include "hw/nvram/fw_cfg.h" diff --git a/tests/libqtest.c b/tests/libqtest.c index 879ffe91dc..bb82069f5c 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -171,12 +171,16 @@ void qtest_quit(QTestState *s) waitpid(pid, &status, 0); } + close(s->fd); + close(s->qmp_fd); + g_string_free(s->rx, true); unlink(s->pid_file); unlink(s->socket_path); unlink(s->qmp_socket_path); g_free(s->pid_file); g_free(s->socket_path); g_free(s->qmp_socket_path); + g_free(s); } static void socket_sendf(int fd, const char *fmt, va_list ap) diff --git a/tests/libqtest.h b/tests/libqtest.h index 437bda39f3..0f6aade092 100644 --- a/tests/libqtest.h +++ b/tests/libqtest.h @@ -17,6 +17,7 @@ #ifndef LIBQTEST_H #define LIBQTEST_H +#include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <stdarg.h> @@ -319,6 +320,17 @@ static inline QTestState *qtest_start(const char *args) } /** + * qtest_end: + * + * Shut down the QEMU process started by qtest_start(). + */ +static inline void qtest_end(void) +{ + qtest_quit(global_qtest); + global_qtest = NULL; +} + +/** * qmp: * @fmt...: QMP message to send to qemu * diff --git a/tests/test-bitops.c b/tests/test-bitops.c new file mode 100644 index 0000000000..4e713e4e00 --- /dev/null +++ b/tests/test-bitops.c @@ -0,0 +1,75 @@ +/* + * Test bitops routines + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include <glib.h> +#include <stdint.h> +#include "qemu/bitops.h" + +typedef struct { + uint32_t value; + int start; + int length; + int32_t result; +} S32Test; + +typedef struct { + uint64_t value; + int start; + int length; + int64_t result; +} S64Test; + +static const S32Test test_s32_data[] = { + { 0x38463983, 4, 4, -8 }, + { 0x38463983, 12, 8, 0x63 }, + { 0x38463983, 0, 32, 0x38463983 }, +}; + +static const S64Test test_s64_data[] = { + { 0x8459826734967223, 60, 4, -8 }, + { 0x8459826734967223, 0, 64, 0x8459826734967223 }, +}; + +static void test_sextract32(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(test_s32_data); i++) { + const S32Test *test = &test_s32_data[i]; + int32_t r = sextract32(test->value, test->start, test->length); + + g_assert_cmpint(r, ==, test->result); + } +} + +static void test_sextract64(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(test_s32_data); i++) { + const S32Test *test = &test_s32_data[i]; + int64_t r = sextract64(test->value, test->start, test->length); + + g_assert_cmpint(r, ==, test->result); + } + + for (i = 0; i < ARRAY_SIZE(test_s64_data); i++) { + const S64Test *test = &test_s64_data[i]; + int64_t r = sextract64(test->value, test->start, test->length); + + g_assert_cmpint(r, ==, test->result); + } +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + g_test_add_func("/bitops/sextract32", test_sextract32); + g_test_add_func("/bitops/sextract64", test_sextract64); + return g_test_run(); +} |