softmmu/qtest: Move the target-specific pseries RTAS code out of qtest.c
Ideally, qtest.c should be independent from target specific code, so we only have to compile it once for all targets. Thus start improving the situation by moving the pseries related code to hw/ppc/spapr_rtas.c instead and allow target code to register a callback handler for such target specific commands. Message-Id: <20230411183418.1640500-2-thuth@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
8708c46306
commit
c7a6bf5d92
@ -33,6 +33,7 @@
|
|||||||
#include "sysemu/cpus.h"
|
#include "sysemu/cpus.h"
|
||||||
#include "sysemu/hw_accel.h"
|
#include "sysemu/hw_accel.h"
|
||||||
#include "sysemu/runstate.h"
|
#include "sysemu/runstate.h"
|
||||||
|
#include "sysemu/qtest.h"
|
||||||
#include "kvm_ppc.h"
|
#include "kvm_ppc.h"
|
||||||
|
|
||||||
#include "hw/ppc/spapr.h"
|
#include "hw/ppc/spapr.h"
|
||||||
@ -548,6 +549,32 @@ uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
|
|||||||
return H_PARAMETER;
|
return H_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool spapr_qtest_callback(CharBackend *chr, gchar **words)
|
||||||
|
{
|
||||||
|
if (strcmp(words[0], "rtas") == 0) {
|
||||||
|
uint64_t res, args, ret;
|
||||||
|
unsigned long nargs, nret;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = qemu_strtoul(words[2], NULL, 0, &nargs);
|
||||||
|
g_assert(rc == 0);
|
||||||
|
rc = qemu_strtou64(words[3], NULL, 0, &args);
|
||||||
|
g_assert(rc == 0);
|
||||||
|
rc = qemu_strtoul(words[4], NULL, 0, &nret);
|
||||||
|
g_assert(rc == 0);
|
||||||
|
rc = qemu_strtou64(words[5], NULL, 0, &ret);
|
||||||
|
g_assert(rc == 0);
|
||||||
|
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
|
||||||
|
|
||||||
|
qtest_send_prefix(chr);
|
||||||
|
qtest_sendf(chr, "OK %"PRIu64"\n", res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
|
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
|
||||||
{
|
{
|
||||||
assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
|
assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
|
||||||
@ -630,6 +657,8 @@ static void core_rtas_register_types(void)
|
|||||||
rtas_ibm_nmi_register);
|
rtas_ibm_nmi_register);
|
||||||
spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
|
spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
|
||||||
rtas_ibm_nmi_interlock);
|
rtas_ibm_nmi_interlock);
|
||||||
|
|
||||||
|
qtest_set_command_cb(spapr_qtest_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(core_rtas_register_types)
|
type_init(core_rtas_register_types)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#ifndef QTEST_H
|
#ifndef QTEST_H
|
||||||
#define QTEST_H
|
#define QTEST_H
|
||||||
|
|
||||||
|
#include "chardev/char.h"
|
||||||
|
|
||||||
extern bool qtest_allowed;
|
extern bool qtest_allowed;
|
||||||
|
|
||||||
@ -22,6 +23,9 @@ static inline bool qtest_enabled(void)
|
|||||||
return qtest_allowed;
|
return qtest_allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qtest_send_prefix(CharBackend *chr);
|
||||||
|
void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
|
||||||
|
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
|
||||||
bool qtest_driver(void);
|
bool qtest_driver(void);
|
||||||
|
|
||||||
void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
|
void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
|
||||||
|
@ -29,10 +29,6 @@
|
|||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
#include CONFIG_DEVICES
|
|
||||||
#ifdef CONFIG_PSERIES
|
|
||||||
#include "hw/ppc/spapr_rtas.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_IRQ 256
|
#define MAX_IRQ 256
|
||||||
|
|
||||||
@ -263,7 +259,7 @@ static int hex2nib(char ch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qtest_send_prefix(CharBackend *chr)
|
void qtest_send_prefix(CharBackend *chr)
|
||||||
{
|
{
|
||||||
if (!qtest_log_fp || !qtest_opened) {
|
if (!qtest_log_fp || !qtest_opened) {
|
||||||
return;
|
return;
|
||||||
@ -302,8 +298,7 @@ static void qtest_send(CharBackend *chr, const char *str)
|
|||||||
qtest_server_send(qtest_server_send_opaque, str);
|
qtest_server_send(qtest_server_send_opaque, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr,
|
void qtest_sendf(CharBackend *chr, const char *fmt, ...)
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
gchar *buffer;
|
gchar *buffer;
|
||||||
@ -361,6 +356,15 @@ static void qtest_clock_warp(int64_t dest)
|
|||||||
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool (*process_command_cb)(CharBackend *chr, gchar **words);
|
||||||
|
|
||||||
|
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
|
||||||
|
{
|
||||||
|
assert(!process_command_cb); /* Switch to a list if we need more than one */
|
||||||
|
|
||||||
|
process_command_cb = pc_cb;
|
||||||
|
}
|
||||||
|
|
||||||
static void qtest_process_command(CharBackend *chr, gchar **words)
|
static void qtest_process_command(CharBackend *chr, gchar **words)
|
||||||
{
|
{
|
||||||
const gchar *command;
|
const gchar *command;
|
||||||
@ -717,25 +721,6 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
|||||||
qtest_sendf(chr, "OK big\n");
|
qtest_sendf(chr, "OK big\n");
|
||||||
#else
|
#else
|
||||||
qtest_sendf(chr, "OK little\n");
|
qtest_sendf(chr, "OK little\n");
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_PSERIES
|
|
||||||
} else if (strcmp(words[0], "rtas") == 0) {
|
|
||||||
uint64_t res, args, ret;
|
|
||||||
unsigned long nargs, nret;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = qemu_strtoul(words[2], NULL, 0, &nargs);
|
|
||||||
g_assert(rc == 0);
|
|
||||||
rc = qemu_strtou64(words[3], NULL, 0, &args);
|
|
||||||
g_assert(rc == 0);
|
|
||||||
rc = qemu_strtoul(words[4], NULL, 0, &nret);
|
|
||||||
g_assert(rc == 0);
|
|
||||||
rc = qemu_strtou64(words[5], NULL, 0, &ret);
|
|
||||||
g_assert(rc == 0);
|
|
||||||
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
|
|
||||||
|
|
||||||
qtest_send_prefix(chr);
|
|
||||||
qtest_sendf(chr, "OK %"PRIu64"\n", res);
|
|
||||||
#endif
|
#endif
|
||||||
} else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
|
} else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
|
||||||
int64_t ns;
|
int64_t ns;
|
||||||
@ -777,6 +762,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
|||||||
qtest_send_prefix(chr);
|
qtest_send_prefix(chr);
|
||||||
qtest_sendf(chr, "OK %"PRIi64"\n",
|
qtest_sendf(chr, "OK %"PRIi64"\n",
|
||||||
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||||
|
} else if (process_command_cb && process_command_cb(chr, words)) {
|
||||||
|
/* Command got consumed by the callback handler */
|
||||||
} else {
|
} else {
|
||||||
qtest_send_prefix(chr);
|
qtest_send_prefix(chr);
|
||||||
qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
|
qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user