---
include/mcdstub/mcdstub.h | 30 +++++++++++++++++
mcdstub/mcdstub.c | 70 +++++++++++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git a/include/mcdstub/mcdstub.h b/include/mcdstub/mcdstub.h
index c3e9c7e9dc..c4370bb177 100644
--- a/include/mcdstub/mcdstub.h
+++ b/include/mcdstub/mcdstub.h
@@ -402,6 +402,18 @@ int process_string_cmd(void *user_ctx, const char *data,
* @params: GArray with all extracted parameters.
*/
int cmd_parse_params(const char *data, const char *schema, GArray *params);
+
+/**
+ * handle_gen_query() - Handler for all TCP query packets.
+ *
+ * Calls :c:func:`process_string_cmd` with all query functions in the
+ * mcd_query_cmds_table. :c:func:`process_string_cmd` then selects the correct
+ * one. This function just passes on the TCP packet data string from the
+ * parameters.
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_gen_query(GArray *params, void *user_ctx);
+
/**
* mcd_get_cpu_index() - Returns the internal CPU index plus one.
*
@@ -415,6 +427,24 @@ int mcd_get_cpu_index(CPUState *cpu);
* @cpu_index: Index of the desired CPU.
*/
CPUState *mcd_get_cpu(uint32_t cpu_index);
+
+/**
+ * handle_query_cores() - Handler for the core query.
+ *
+ * This function sends the type of core and number of cores currently
+ * simulated by QEMU. It also sends a device name for the MCD data structure.
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_query_cores(GArray *params, void *user_ctx);
+
+/**
+ * handle_query_system() - Handler for the system query.
+ *
+ * Sends the system name, which is "qemu-system".
+ * @params: GArray with all TCP packet parameters.
+ */
+void handle_query_system(GArray *params, void *user_ctx);
+
/**
* get_first_cpu_in_process() - Returns the first CPU in the provided process.
*
diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c
index 858e79632b..a090268e70 100644
--- a/mcdstub/mcdstub.c
+++ b/mcdstub/mcdstub.c
@@ -81,6 +81,20 @@ void init_query_cmds_table(MCDCmdParseEntry *mcd_query_cmds_table)
/* initalizes a list of all query commands */
int cmd_number = 0;
+ MCDCmdParseEntry query_system = {
+ .handler = handle_query_system,
+ .cmd = QUERY_ARG_SYSTEM,
+ };
+ mcd_query_cmds_table[cmd_number] = query_system;
+ cmd_number++;
+
+ MCDCmdParseEntry query_cores = {
+ .handler = handle_query_cores,
+ .cmd = QUERY_ARG_CORES,
+ };
+ mcd_query_cmds_table[cmd_number] = query_cores;
+ cmd_number++;
+
void reset_mcdserver_state(void)
{
g_free(mcdserver_state.processes);
@@ -345,6 +359,17 @@ int mcd_handle_packet(const char *line_buf)
error_report("QEMU: Terminated via MCDstub");
mcd_exit(0);
exit(0);
+ case TCP_CHAR_QUERY:
+ {
+ static MCDCmdParseEntry query_cmd_desc = {
+ .handler = handle_gen_query,
+ };
+ query_cmd_desc.cmd = (char[2]) { TCP_CHAR_QUERY, '\0' };
+ strcpy(query_cmd_desc.schema,
+ (char[2]) { ARG_SCHEMA_STRING, '\0' });
+ cmd_parser = &query_cmd_desc;
+ }
+ break;
case TCP_CHAR_CLOSE_SERVER:
{
static MCDCmdParseEntry close_server_cmd_desc = {
@@ -368,6 +393,20 @@ int mcd_handle_packet(const char *line_buf)
return RS_IDLE;
}
+
+void handle_gen_query(GArray *params, void *user_ctx)
+{
+ if (!params->len) {
+ return;
+ }
+ /* iterate over all possible query functions and execute the right one */
+ if (process_string_cmd(NULL, get_param(params, 0)->data,
+ mcdserver_state.mcd_query_cmds_table,
+ ARRAY_SIZE(mcdserver_state.mcd_query_cmds_table))) {
+ mcd_put_packet("");
+ }
+}
+
void run_cmd_parser(const char *data, const MCDCmdParseEntry *cmd)
{
if (!data) {
@@ -735,6 +774,37 @@ void handle_open_server(GArray *params, void *user_ctx)
mcd_put_packet(TCP_HANDSHAKE_SUCCESS);
}
+void handle_query_system(GArray *params, void *user_ctx)
+{
+ mcd_put_packet(MCD_SYSTEM_NAME);
+}
+
+void handle_query_cores(GArray *params, void *user_ctx)
+{
+ /* get first cpu */
+ CPUState *cpu = mcd_first_attached_cpu();
+ if (!cpu) {
+ return;
+ }
+
+ ObjectClass *oc = object_get_class(OBJECT(cpu));
+ const char *cpu_model = object_class_get_name(oc);
+
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+ const gchar *arch = cc->gdb_arch_name(cpu);
+
+ uint32_t nr_cores = cpu->nr_cores;
+ char device_name[ARGUMENT_STRING_LENGTH] = {0};
+ if (arch) {
+ snprintf(device_name, sizeof(device_name), "%s",
+ DEVICE_NAME_TEMPLATE(arch));
+ }
+ g_string_printf(mcdserver_state.str_buf, "%s=%s.%s=%s.%s=%u.",
+ TCP_ARGUMENT_DEVICE, device_name, TCP_ARGUMENT_CORE, cpu_model,
+ TCP_ARGUMENT_AMOUNT_CORE, nr_cores);
+ mcd_put_strbuf();
+}
+
void handle_close_server(GArray *params, void *user_ctx)
{
--
2.34.1