| /* | 
 |  * QTest testcase for the IB700 watchdog | 
 |  * | 
 |  * Copyright (c) 2014 Red Hat, Inc. | 
 |  * | 
 |  * 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 <string.h> | 
 | #include "libqtest.h" | 
 | #include "qemu/osdep.h" | 
 |  | 
 | #define NS_PER_SEC 1000000000ULL | 
 |  | 
 | static void qmp_check_no_event(void) | 
 | { | 
 |     QDict *resp = qmp("{'execute':'query-status'}"); | 
 |     g_assert(qdict_haskey(resp, "return")); | 
 |     QDECREF(resp); | 
 | } | 
 |  | 
 | static QDict *qmp_get_event(const char *name) | 
 | { | 
 |     QDict *event = qmp(""); | 
 |     QDict *data; | 
 |     g_assert(qdict_haskey(event, "event")); | 
 |     g_assert(!strcmp(qdict_get_str(event, "event"), name)); | 
 |  | 
 |     if (qdict_haskey(event, "data")) { | 
 |         data = qdict_get_qdict(event, "data"); | 
 |         QINCREF(data); | 
 |     } else { | 
 |         data = NULL; | 
 |     } | 
 |  | 
 |     QDECREF(event); | 
 |     return data; | 
 | } | 
 |  | 
 | static QDict *ib700_program_and_wait(QTestState *s) | 
 | { | 
 |     clock_step(NS_PER_SEC * 40); | 
 |     qmp_check_no_event(); | 
 |  | 
 |     /* 2 second limit */ | 
 |     outb(0x443, 14); | 
 |  | 
 |     /* Ping */ | 
 |     clock_step(NS_PER_SEC); | 
 |     qmp_check_no_event(); | 
 |     outb(0x443, 14); | 
 |  | 
 |     /* Disable */ | 
 |     clock_step(NS_PER_SEC); | 
 |     qmp_check_no_event(); | 
 |     outb(0x441, 1); | 
 |     clock_step(3 * NS_PER_SEC); | 
 |     qmp_check_no_event(); | 
 |  | 
 |     /* Enable and let it fire */ | 
 |     outb(0x443, 13); | 
 |     clock_step(3 * NS_PER_SEC); | 
 |     qmp_check_no_event(); | 
 |     clock_step(2 * NS_PER_SEC); | 
 |     return qmp_get_event("WATCHDOG"); | 
 | } | 
 |  | 
 |  | 
 | static void ib700_pause(void) | 
 | { | 
 |     QDict *d; | 
 |     QTestState *s = qtest_start("-watchdog-action pause -device ib700"); | 
 |     qtest_irq_intercept_in(s, "ioapic"); | 
 |     d = ib700_program_and_wait(s); | 
 |     g_assert(!strcmp(qdict_get_str(d, "action"), "pause")); | 
 |     QDECREF(d); | 
 |     d = qmp_get_event("STOP"); | 
 |     QDECREF(d); | 
 |     qtest_end(); | 
 | } | 
 |  | 
 | static void ib700_reset(void) | 
 | { | 
 |     QDict *d; | 
 |     QTestState *s = qtest_start("-watchdog-action reset -device ib700"); | 
 |     qtest_irq_intercept_in(s, "ioapic"); | 
 |     d = ib700_program_and_wait(s); | 
 |     g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); | 
 |     QDECREF(d); | 
 |     d = qmp_get_event("RESET"); | 
 |     QDECREF(d); | 
 |     qtest_end(); | 
 | } | 
 |  | 
 | static void ib700_shutdown(void) | 
 | { | 
 |     QDict *d; | 
 |     QTestState *s = qtest_start("-watchdog-action reset -no-reboot -device ib700"); | 
 |     qtest_irq_intercept_in(s, "ioapic"); | 
 |     d = ib700_program_and_wait(s); | 
 |     g_assert(!strcmp(qdict_get_str(d, "action"), "reset")); | 
 |     QDECREF(d); | 
 |     d = qmp_get_event("SHUTDOWN"); | 
 |     QDECREF(d); | 
 |     qtest_end(); | 
 | } | 
 |  | 
 | static void ib700_none(void) | 
 | { | 
 |     QDict *d; | 
 |     QTestState *s = qtest_start("-watchdog-action none -device ib700"); | 
 |     qtest_irq_intercept_in(s, "ioapic"); | 
 |     d = ib700_program_and_wait(s); | 
 |     g_assert(!strcmp(qdict_get_str(d, "action"), "none")); | 
 |     QDECREF(d); | 
 |     qtest_end(); | 
 | } | 
 |  | 
 | int main(int argc, char **argv) | 
 | { | 
 |     int ret; | 
 |  | 
 |     g_test_init(&argc, &argv, NULL); | 
 |     qtest_add_func("/wdt_ib700/pause", ib700_pause); | 
 |     qtest_add_func("/wdt_ib700/reset", ib700_reset); | 
 |     qtest_add_func("/wdt_ib700/shutdown", ib700_shutdown); | 
 |     qtest_add_func("/wdt_ib700/none", ib700_none); | 
 |  | 
 |     ret = g_test_run(); | 
 |  | 
 |     return ret; | 
 | } |