diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile | 7 | ||||
-rw-r--r-- | tests/boot-order-test.c | 209 | ||||
-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 |
13 files changed, 303 insertions, 69 deletions
diff --git a/tests/Makefile b/tests/Makefile index 279d5f8307..425a9a8c4b 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -57,6 +57,7 @@ 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) @@ -69,6 +70,8 @@ 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 @@ -125,7 +128,7 @@ tests/test-mul64$(EXESUF): tests/test-mul64.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 @@ -134,6 +137,7 @@ tests/m48t59-test$(EXESUF): tests/m48t59-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 +230,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/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 * |