From nobody Tue Feb 10 15:44:46 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1696583596783903.4393882362132; Fri, 6 Oct 2023 02:13:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qogn8-00087A-41; Fri, 06 Oct 2023 05:06:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qogn1-00083j-H1 for qemu-devel@nongnu.org; Fri, 06 Oct 2023 05:06:32 -0400 Received: from smtp1.lauterbach.com ([62.154.241.196]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qogmw-0000wB-Jj for qemu-devel@nongnu.org; Fri, 06 Oct 2023 05:06:31 -0400 Received: (qmail 19535 invoked by uid 484); 6 Oct 2023 09:06:23 -0000 Received: from nedpc1.intern.lauterbach.com (Authenticated_SSL:neder@[10.2.11.92]) (envelope-sender ) by smtp1.lauterbach.com (qmail-ldap-1.03) with TLS_AES_256_GCM_SHA384 encrypted SMTP for ; 6 Oct 2023 09:06:22 -0000 X-Qmail-Scanner-Diagnostics: from nedpc1.intern.lauterbach.com by smtp1.lauterbach.com (envelope-from , uid 484) with qmail-scanner-2.11 (mhr: 1.0. clamdscan: 0.99/21437. spamassassin: 3.4.0. Clear:RC:1(10.2.11.92):. Processed in 0.07364 secs); 06 Oct 2023 09:06:23 -0000 From: Nicolas Eder To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Christian.Boenig@lauterbach.com, =?UTF-8?q?Alex=20Benn=C3=A9e?= , Nicolas Eder Subject: [PATCH v2 09/29] memory and register query data now stored per core Date: Fri, 6 Oct 2023 11:05:50 +0200 Message-Id: <20231006090610.26171-10-nicolas.eder@lauterbach.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231006090610.26171-1-nicolas.eder@lauterbach.com> References: <20231006090610.26171-1-nicolas.eder@lauterbach.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Qmail-Scanner-2.11: added fake Content-Type header Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=62.154.241.196; envelope-from=nicolas.eder@lauterbach.com; helo=smtp1.lauterbach.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1696583599294100011 Content-Type: text/plain; charset="utf-8" From: neder --- mcdstub/internals.h | 63 +++- mcdstub/mcd_shared_defines.h | 43 ++- mcdstub/mcdstub.c | 693 ++++++++++++++++++++++------------- 3 files changed, 533 insertions(+), 266 deletions(-) diff --git a/mcdstub/internals.h b/mcdstub/internals.h index 4c79ff7674..a4d49a4a84 100644 --- a/mcdstub/internals.h +++ b/mcdstub/internals.h @@ -8,6 +8,7 @@ =20 #include "exec/cpu-common.h" #include "chardev/char.h" +#include "hw/core/cpu.h" // just used for the register xml files #include "exec/gdbstub.h" /* xml_builtin */ =20 @@ -22,9 +23,22 @@ #define MCD_TRIG_ACTION_DBG_DEBUG 0x00000001 =20 // schema defines -#define ARG_SCHEMA_QRYHANDLE "q" -#define ARG_SCHEMA_STRING "s" -#define ARG_SCHEMA_CORENUM "c"=20 +#define ARG_SCHEMA_QRYHANDLE 'q' +#define ARG_SCHEMA_STRING 's' +#define ARG_SCHEMA_CORENUM 'c' + +// resets +#define RESET_SYSTEM "full_system_reset" +#define RESET_GPR "gpr_reset" +#define RESET_MEMORY "memory_reset" + +// more +#define QUERY_TOTAL_NUMBER 11 //FIXME: set this to a usefull value in the = end +#define CMD_SCHEMA_LENGTH 2 +#define MCD_MAX_CORES 128 +#define MCD_SYSTEM_NAME "qemu-system" +// tcp query packet values templates +#define DEVICE_NAME_TEMPLATE(s) "qemu-" #s "-device" =20 // GDB stuff thats needed for GDB function, which we use typedef struct GDBRegisterState { @@ -52,8 +66,7 @@ typedef void (*MCDCmdHandler)(GArray *params, void *user_= ctx); typedef struct MCDCmdParseEntry { MCDCmdHandler handler; const char *cmd; - bool cmd_startswith; - const char *schema; + char schema[CMD_SCHEMA_LENGTH]; } MCDCmdParseEntry; =20 typedef enum MCDThreadIdKind { @@ -92,6 +105,13 @@ enum RSState { RS_DATAEND, }; =20 +typedef struct mcd_trigger_st { + uint32_t type; + uint32_t option; + uint32_t action; + uint32_t nr_trigger; +} mcd_trigger_st; + typedef struct MCDState { bool init; /* have we been initialised? */ CPUState *c_cpu; /* current CPU for everything */ @@ -113,9 +133,13 @@ typedef struct MCDState { int supported_sstep_flags; =20 // my stuff - GArray *memspaces; - GArray *reggroups; - GArray *registers; + uint32_t query_cpu_id; + GList *all_memspaces; + GList *all_reggroups; + GList *all_registers; + GArray *resets; + mcd_trigger_st trigger; + MCDCmdParseEntry mcd_query_cmds_table[QUERY_TOTAL_NUMBER]; } MCDState; =20 /* lives in main mcdstub.c */ @@ -164,6 +188,11 @@ typedef struct mcd_reg_st { uint8_t opc2; } mcd_reg_st; =20 +typedef struct mcd_reset_st { + const char *name; + uint8_t id; +} mcd_reset_st; + // Inline utility function, convert from int to hex and back =20 =20 @@ -194,6 +223,9 @@ void mcd_sigterm_handler(int signal); #endif =20 void mcd_init_mcdserver_state(void); +void init_query_cmds_table(MCDCmdParseEntry* mcd_query_cmds_table); +int init_resets(GArray* resets); +int init_trigger(mcd_trigger_st* trigger); void reset_mcdserver_state(void); void create_processes(MCDState *s); void mcd_create_default_process(MCDState *s); @@ -231,8 +263,10 @@ void handle_query_system(GArray *params, void *user_ct= x); CPUState *get_first_cpu_in_process(MCDProcess *process); CPUState *find_cpu(uint32_t thread_id); void handle_open_core(GArray *params, void *user_ctx); -void handle_query_reset(GArray *params, void *user_ctx); -void handle_detach(GArray *params, void *user_ctx); +void handle_query_reset_f(GArray *params, void *user_ctx); +void handle_query_reset_c(GArray *params, void *user_ctx); +void handle_close_server(GArray *params, void *user_ctx); +void handle_close_core(GArray *params, void *user_ctx); void handle_query_trigger(GArray *params, void *user_ctx); void mcd_continue(void); void handle_query_reg_groups_f(GArray *params, void *user_ctx); @@ -241,11 +275,14 @@ void handle_query_mem_spaces_f(GArray *params, void *= user_ctx); void handle_query_mem_spaces_c(GArray *params, void *user_ctx); void handle_query_regs_f(GArray *params, void *user_ctx); void handle_query_regs_c(GArray *params, void *user_ctx); -void handle_init(GArray *params, void *user_ctx); -void parse_reg_xml(const char *xml, int size); +void handle_open_server(GArray *params, void *user_ctx); +void parse_reg_xml(const char *xml, int size, GArray* registers); =20 // arm specific functions -void mcd_arm_store_mem_spaces(int nr_address_spaces); +int mcd_arm_store_mem_spaces(CPUState *cpu, GArray* memspaces); +int mcd_arm_parse_core_xml_file(CPUClass *cc, GArray* reggroups, GArray* r= egisters, int* current_group_id); +int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray* reggroups, GArr= ay* registers, int* current_group_id); +int mcd_arm_get_additional_register_info(GArray* reggroups, GArray* regist= ers); =20 /* sycall handling */ void mcd_syscall_reset(void); diff --git a/mcdstub/mcd_shared_defines.h b/mcdstub/mcd_shared_defines.h index 6a2abfb1bc..e0b27ce5e6 100644 --- a/mcdstub/mcd_shared_defines.h +++ b/mcdstub/mcd_shared_defines.h @@ -3,12 +3,13 @@ #ifndef MCD_SHARED_DEFINES #define MCD_SHARED_DEFINES =20 -// tcp characters -#define TCP_CHAR_INIT 'i' +// tcp data characters +#define TCP_CHAR_OPEN_SERVER 'I' +#define TCP_CHAR_OPEN_CORE 'i' #define TCP_CHAR_GO 'c' #define TCP_CHAR_QUERY 'q' -#define TCP_CHAR_OPEN_CORE 'H' -#define TCP_CHAR_DETACH 'D' +#define TCP_CHAR_CLOSE_SERVER 'D' +#define TCP_CHAR_CLOSE_CORE 'd' #define TCP_CHAR_KILLQEMU 'k' =20 // tcp protocol chars @@ -18,7 +19,39 @@ #define TCP_COMMAND_END '#' #define TCP_WAS_LAST '|' #define TCP_WAS_NOT_LAST '~' +#define TCP_HANDSHAKE_SUCCESS "shaking your hand" =20 +// tcp query arguments +#define QUERY_FIRST "f" +#define QUERY_CONSEQUTIVE "c" =20 +#define QUERY_ARG_SYSTEM "system" +#define QUERY_ARG_CORES "cores" +#define QUERY_ARG_RESET "reset" +#define QUERY_ARG_TRIGGER "trigger" +#define QUERY_ARG_MEMORY "memory" +#define QUERY_ARG_REGGROUP "reggroup" +#define QUERY_ARG_REG "reg" =20 -#endif \ No newline at end of file +// tcp query packet argument list +#define TCP_ARGUMENT_NAME "name" +#define TCP_ARGUMENT_ID "id" +#define TCP_ARGUMENT_TYPE "type" +#define TCP_ARGUMENT_BITS_PER_MAU "bpm" +#define TCP_ARGUMENT_INVARIANCE "i" +#define TCP_ARGUMENT_ENDIAN "e" +#define TCP_ARGUMENT_MIN "min" +#define TCP_ARGUMENT_MAX "max" +#define TCP_ARGUMENT_SUPPORTED_ACCESS_OPTIONS "sao" +#define TCP_ARGUMENT_REGGROUPID "reggroupid" +#define TCP_ARGUMENT_MEMSPACEID "memspaceid" +#define TCP_ARGUMENT_SIZE "size" +#define TCP_ARGUMENT_THREAD "thread" +#define TCP_ARGUMENT_DEVICE "device" +#define TCP_ARGUMENT_CORE "core" +#define TCP_ARGUMENT_AMOUNT_CORE "nr_cores" +#define TCP_ARGUMENT_AMOUNT_TRIGGER "nr_trigger" +#define TCP_ARGUMENT_OPTION "option" +#define TCP_ARGUMENT_ACTION "action" + +#endif diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c index a4841cf7d3..a0c4c2794f 100644 --- a/mcdstub/mcdstub.c +++ b/mcdstub/mcdstub.c @@ -27,7 +27,6 @@ #include "exec/tb-flush.h" #include "sysemu/cpus.h" #include "sysemu/replay.h" -#include "hw/core/cpu.h" #include "chardev/char.h" #include "chardev/char-fe.h" #include "monitor/monitor.h" @@ -47,53 +46,6 @@ MCDSystemState mcdserver_system_state; =20 MCDState mcdserver_state; =20 -static const MCDCmdParseEntry mcd_gen_query_table[] =3D { - // this is a list of all query commands. it gets iterated over only th= e handler of the matching command will get executed - { - .handler =3D handle_query_system, - .cmd =3D "system", - }, - { - .handler =3D handle_query_cores, - .cmd =3D "cores", - }, - { - .handler =3D handle_query_reset, - .cmd =3D "reset", - }, - { - .handler =3D handle_query_trigger, - .cmd =3D "trigger", - }, - { - .handler =3D handle_query_mem_spaces_f, - .cmd =3D "memoryf", - }, - { - .handler =3D handle_query_mem_spaces_c, - .cmd =3D "memoryc", - .schema =3D ARG_SCHEMA_QRYHANDLE, - }, - { - .handler =3D handle_query_reg_groups_f, - .cmd =3D "reggroupf", - }, - { - .handler =3D handle_query_reg_groups_c, - .cmd =3D "reggroupc", - .schema =3D ARG_SCHEMA_QRYHANDLE, - }, - { - .handler =3D handle_query_regs_f, - .cmd =3D "regf", - }, - { - .handler =3D handle_query_regs_c, - .cmd =3D "regc", - .schema =3D ARG_SCHEMA_QRYHANDLE, - }, -}; - void mcd_init_mcdserver_state(void) { g_assert(!mcdserver_state.init); @@ -113,6 +65,97 @@ void mcd_init_mcdserver_state(void) mcdserver_state.supported_sstep_flags =3D accel_supported_gdbstub_sste= p_flags(); mcdserver_state.sstep_flags =3D SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOT= IMER; mcdserver_state.sstep_flags &=3D mcdserver_state.supported_sstep_flags; + + // init query table + init_query_cmds_table(mcdserver_state.mcd_query_cmds_table); +} + +void init_query_cmds_table(MCDCmdParseEntry* mcd_query_cmds_table) { + // initalizes a list of all query commands + int cmd_number =3D 0; + + MCDCmdParseEntry query_system =3D { + .handler =3D handle_query_system, + .cmd =3D QUERY_ARG_SYSTEM, + }; + mcd_query_cmds_table[cmd_number] =3D query_system; + cmd_number++; + + MCDCmdParseEntry query_cores =3D { + .handler =3D handle_query_cores, + .cmd =3D QUERY_ARG_CORES, + }; + mcd_query_cmds_table[cmd_number] =3D query_cores; + cmd_number++; + + MCDCmdParseEntry query_reset_f =3D { + .handler =3D handle_query_reset_f, + .cmd =3D QUERY_ARG_RESET QUERY_FIRST, + }; + mcd_query_cmds_table[cmd_number] =3D query_reset_f; + cmd_number++; + + MCDCmdParseEntry query_reset_c =3D { + .handler =3D handle_query_reset_c, + .cmd =3D QUERY_ARG_RESET QUERY_CONSEQUTIVE, + }; + strcpy(query_reset_c.schema, (char[2]) { (char) ARG_SCHEMA_QRYHANDLE, = '\0' }); + mcd_query_cmds_table[cmd_number] =3D query_reset_c; + cmd_number++; + + MCDCmdParseEntry query_trigger =3D { + .handler =3D handle_query_trigger, + .cmd =3D QUERY_ARG_TRIGGER, + }; + mcd_query_cmds_table[cmd_number] =3D query_trigger; + cmd_number++; + + MCDCmdParseEntry query_mem_spaces_f =3D { + .handler =3D handle_query_mem_spaces_f, + .cmd =3D QUERY_ARG_MEMORY QUERY_FIRST, + }; + strcpy(query_mem_spaces_f.schema, (char[2]) { (char) ARG_SCHEMA_CORENU= M, '\0' }); + mcd_query_cmds_table[cmd_number] =3D query_mem_spaces_f; + cmd_number++; + + MCDCmdParseEntry query_mem_spaces_c =3D { + .handler =3D handle_query_mem_spaces_c, + .cmd =3D QUERY_ARG_MEMORY QUERY_CONSEQUTIVE, + }; + strcpy(query_mem_spaces_c.schema, (char[2]) { (char) ARG_SCHEMA_QRYHAN= DLE, '\0' }); + mcd_query_cmds_table[cmd_number] =3D query_mem_spaces_c; + cmd_number++; + + MCDCmdParseEntry query_reg_groups_f =3D { + .handler =3D handle_query_reg_groups_f, + .cmd =3D QUERY_ARG_REGGROUP QUERY_FIRST, + }; + strcpy(query_reg_groups_f.schema, (char[2]) { (char) ARG_SCHEMA_CORENU= M, '\0' }); + mcd_query_cmds_table[cmd_number] =3D query_reg_groups_f; + cmd_number++; + + MCDCmdParseEntry query_reg_groups_c =3D { + .handler =3D handle_query_reg_groups_c, + .cmd =3D QUERY_ARG_REGGROUP QUERY_CONSEQUTIVE, + }; + strcpy(query_reg_groups_c.schema, (char[2]) { (char) ARG_SCHEMA_QRYHAN= DLE, '\0' }); + mcd_query_cmds_table[cmd_number] =3D query_reg_groups_c; + cmd_number++; + + MCDCmdParseEntry query_regs_f =3D { + .handler =3D handle_query_regs_f, + .cmd =3D QUERY_ARG_REG QUERY_FIRST, + }; + strcpy(query_regs_f.schema, (char[2]) { (char) ARG_SCHEMA_CORENUM, '\0= ' }); + mcd_query_cmds_table[cmd_number] =3D query_regs_f; + cmd_number++; + + MCDCmdParseEntry query_regs_c =3D { + .handler =3D handle_query_regs_c, + .cmd =3D QUERY_ARG_REG QUERY_CONSEQUTIVE, + }; + strcpy(query_regs_c.schema, (char[2]) { (char) ARG_SCHEMA_QRYHANDLE, '= \0' }); + mcd_query_cmds_table[cmd_number] =3D query_regs_c; } =20 void reset_mcdserver_state(void) @@ -400,14 +443,14 @@ int mcd_handle_packet(const char *line_buf) const MCDCmdParseEntry *cmd_parser =3D NULL; =20 switch (line_buf[0]) { - case TCP_CHAR_INIT: + case TCP_CHAR_OPEN_SERVER: // handshake and lookup initialization { - static MCDCmdParseEntry init_cmd_desc =3D { - .handler =3D handle_init, + static MCDCmdParseEntry open_server_cmd_desc =3D { + .handler =3D handle_open_server, }; - init_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_INIT, '\0' }; - cmd_parser =3D &init_cmd_desc; + open_server_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_OPEN_= SERVER, '\0' }; + cmd_parser =3D &open_server_cmd_desc; } break; case TCP_CHAR_GO: @@ -430,29 +473,39 @@ int mcd_handle_packet(const char *line_buf) { static MCDCmdParseEntry query_cmd_desc =3D { .handler =3D handle_gen_query, - .schema =3D ARG_SCHEMA_STRING }; query_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_QUERY, '\0'= }; + strcpy(query_cmd_desc.schema, (char[2]) { (char) ARG_SCHEMA_ST= RING, '\0' }); cmd_parser =3D &query_cmd_desc; } break; case TCP_CHAR_OPEN_CORE: { - static MCDCmdParseEntry gen_open_core =3D { + static MCDCmdParseEntry open_core_cmd_desc =3D { .handler =3D handle_open_core, - .schema =3D ARG_SCHEMA_CORENUM }; - gen_open_core.cmd =3D (char[2]) { (char) TCP_CHAR_OPEN_CORE, '= \0' }; - cmd_parser =3D &gen_open_core; + open_core_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_OPEN_CO= RE, '\0' }; + strcpy(open_core_cmd_desc.schema, (char[2]) { (char) ARG_SCHEM= A_CORENUM, '\0' }); + cmd_parser =3D &open_core_cmd_desc; } break; - case TCP_CHAR_DETACH: + case TCP_CHAR_CLOSE_SERVER: { - static MCDCmdParseEntry detach_cmd_desc =3D { - .handler =3D handle_detach, + static MCDCmdParseEntry close_server_cmd_desc =3D { + .handler =3D handle_close_server, }; - detach_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_DETACH, '\= 0' }; - cmd_parser =3D &detach_cmd_desc; + close_server_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_CLOS= E_SERVER, '\0' }; + cmd_parser =3D &close_server_cmd_desc; + } + break; + case TCP_CHAR_CLOSE_CORE: + { + static MCDCmdParseEntry close_core_cmd_desc =3D { + .handler =3D handle_close_core, + }; + close_core_cmd_desc.cmd =3D (char[2]) { (char) TCP_CHAR_CLOSE_= CORE, '\0' }; + strcpy(close_core_cmd_desc.schema, (char[2]) { (char) ARG_SCHE= MA_CORENUM, '\0' }); + cmd_parser =3D &close_core_cmd_desc; } break; default: @@ -488,8 +541,8 @@ void handle_gen_query(GArray *params, void *user_ctx) } //now iterate over all possible query functions and execute the right = one if (process_string_cmd(NULL, get_param(params, 0)->data, - mcd_gen_query_table, - ARRAY_SIZE(mcd_gen_query_table))) { + mcdserver_state.mcd_query_cmds_table, + ARRAY_SIZE(mcdserver_state.mcd_query_cmds_table= ))) { mcd_put_packet(""); } } @@ -514,16 +567,16 @@ int cmd_parse_params(const char *data, const char *sc= hema, GArray *params) { MCDCmdVariant this_param; =20 char data_buffer[64] =3D {0}; - if (schema[0] =3D=3D atoi(ARG_SCHEMA_STRING)) { + if (schema[0] =3D=3D ARG_SCHEMA_STRING) { this_param.data =3D data; g_array_append_val(params, this_param); } - else if (schema[0] =3D=3D atoi(ARG_SCHEMA_QRYHANDLE)) { + else if (schema[0] =3D=3D ARG_SCHEMA_QRYHANDLE) { strncat(data_buffer, data, strlen(data)); this_param.query_handle =3D atoi(data_buffer); g_array_append_val(params, this_param); } - else if (schema[0] =3D=3D atoi(ARG_SCHEMA_CORENUM)) { + else if (schema[0] =3D=3D ARG_SCHEMA_CORENUM) { strncat(data_buffer, data, strlen(data)); this_param.cpu_id =3D atoi(data_buffer); g_array_append_val(params, this_param); @@ -799,7 +852,7 @@ CPUState *find_cpu(uint32_t thread_id) } =20 =20 -void parse_reg_xml(const char *xml, int size) { +void parse_reg_xml(const char *xml, int size, GArray* registers) { // iterates over the complete xml file int i, j; int still_to_skip =3D 0; @@ -866,7 +919,7 @@ void parse_reg_xml(const char *xml, int size) { } } // store register - g_array_append_vals(mcdserver_state.registers, (gconstpoin= ter)&my_register, 1); + g_array_append_vals(registers, (gconstpointer)&my_register= , 1); // free memory g_array_free(reg_data, false); } @@ -924,7 +977,9 @@ int int_cmp(gconstpointer a, gconstpointer b) { } } =20 -void mcd_arm_store_mem_spaces(int nr_address_spaces) { +int mcd_arm_store_mem_spaces(CPUState *cpu, GArray* memspaces) { + int nr_address_spaces =3D cpu->num_ases; + mcd_mem_space_st space1 =3D { .name =3D "Non Secure", .id =3D 1, @@ -936,7 +991,7 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space1,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space1, 1); =20 mcd_mem_space_st space2 =3D { .name =3D "Physical (Non Secure)", @@ -949,7 +1004,7 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space2,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space2, 1); =20 if (nr_address_spaces=3D=3D2) { mcd_mem_space_st space3 =3D { @@ -963,7 +1018,7 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space3,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space3, 1); mcd_mem_space_st space4 =3D { .name =3D "Physical (Secure)", .id =3D 4, @@ -975,7 +1030,7 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space4,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space4, 1); } // TODO: get dynamically how the per (CP15) space is called mcd_mem_space_st space5 =3D { @@ -989,7 +1044,7 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space5,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space5, 1); mcd_mem_space_st space6 =3D { .name =3D "CP15 Registers", .id =3D 6, @@ -1001,16 +1056,43 @@ void mcd_arm_store_mem_spaces(int nr_address_spaces= ) { .max_addr =3D -1, .supported_access_options =3D 0, }; - g_array_append_vals(mcdserver_state.memspaces, (gconstpointer)&space6,= 1); + g_array_append_vals(memspaces, (gconstpointer)&space6, 1); + + return 0; +} + +int init_resets(GArray* resets) { + mcd_reset_st system_reset =3D { .id =3D 0, .name =3D RESET_SYSTEM}; + mcd_reset_st gpr_reset =3D { .id =3D 1, .name =3D RESET_GPR}; + mcd_reset_st memory_reset =3D { .id =3D 2, .name =3D RESET_MEMORY}; + g_array_append_vals(resets, (gconstpointer)&system_reset, 1); + g_array_append_vals(resets, (gconstpointer)&gpr_reset, 1); + g_array_append_vals(resets, (gconstpointer)&memory_reset, 1); + return 0; } =20 -void handle_init(GArray *params, void *user_ctx) { - // the mcdserver is set up and we return the handshake - mcd_put_packet("shaking your hand");=20 +int init_trigger(mcd_trigger_st* trigger) { + trigger->type =3D (MCD_TRIG_TYPE_IP | MCD_TRIG_TYPE_READ | MCD_TRIG_TY= PE_WRITE | MCD_TRIG_TYPE_RW); + trigger->option =3D (MCD_TRIG_OPT_DATA_IS_CONDITION); + trigger->action =3D (MCD_TRIG_ACTION_DBG_DEBUG); + trigger->nr_trigger =3D 4; + return 0; +} + +void handle_open_server(GArray *params, void *user_ctx) { + // initialize some core-independent data + int return_value =3D 0; + mcdserver_state.resets =3D g_array_new(false, true, sizeof(mcd_reset_s= t)); + return_value =3D init_resets(mcdserver_state.resets); + if (return_value!=3D0) assert(0); + return_value =3D init_trigger(&mcdserver_state.trigger); + if (return_value!=3D0) assert(0); + + mcd_put_packet(TCP_HANDSHAKE_SUCCESS);=20 } =20 void handle_query_system(GArray *params, void *user_ctx) { - mcd_put_packet("qemu-system"); + mcd_put_packet(MCD_SYSTEM_NAME); } =20 void handle_query_cores(GArray *params, void *user_ctx) { @@ -1030,138 +1112,179 @@ void handle_query_cores(GArray *params, void *use= r_ctx) { =20 int nr_cores =3D cpu->nr_cores; =20 - g_string_append_printf(mcdserver_state.str_buf, "device=3D\"qemu-%s-de= vice\",core=3D\"%s\",nr_cores=3D\"%d\"", arch, cpu_model, nr_cores); + char device_name[] =3D DEVICE_NAME_TEMPLATE(arch); + g_string_printf(mcdserver_state.str_buf, "%s=3D%s.%s=3D%s.%s=3D%d.", + TCP_ARGUMENT_DEVICE, device_name, TCP_ARGUMENT_CORE, cpu_model, TCP_AR= GUMENT_AMOUNT_CORE, nr_cores); mcd_put_strbuf(); g_free(arch); } =20 -void handle_open_core(GArray *params, void *user_ctx) { - // get the cpu whith the given id - uint32_t cpu_id =3D get_param(params, 0)->cpu_id; - - CPUState *cpu =3D mcd_get_cpu(cpu_id); - - CPUClass *cc =3D CPU_GET_CLASS(cpu); - - gchar *arch =3D cc->gdb_arch_name(cpu); - - // TODO: this might cause a memory leak when called a second time -> m= aybe free the Garray first - mcdserver_state.memspaces =3D g_array_new(false, true, sizeof(mcd_mem_= space_st)); - mcdserver_state.reggroups =3D g_array_new(false, true, sizeof(mcd_reg_= group_st)); - mcdserver_state.registers =3D g_array_new(false, true, sizeof(mcd_reg_= st)); - - =20 - if (strcmp(arch, "arm")=3D=3D0) { - // store reg groups - uint32_t current_group_id =3D 0; - - // at the moment we just assume there are 3 spaces (gpr, per and d= ebug) - =20 - // store mem spaces - int nr_address_spaces =3D cpu->num_ases; - mcd_arm_store_mem_spaces(nr_address_spaces); - // mem spaces done - - - GList *register_numbers =3D NULL; +int mcd_arm_parse_core_xml_file(CPUClass *cc, GArray* reggroups, GArray* r= egisters, int* current_group_id) { + const char *xml_filename =3D NULL; + const char *current_xml_filename =3D NULL; + const char *xml_content =3D NULL; + int i =3D 0; + + // 1. get correct file + xml_filename =3D cc->gdb_core_xml_file; + for (i =3D 0; ; i++) { + current_xml_filename =3D xml_builtin[i][0]; + if (!current_xml_filename || (strncmp(current_xml_filename, xml_fi= lename, strlen(xml_filename)) =3D=3D 0 + && strlen(current_xml_filename) =3D=3D strlen(xml_filename))) + break; + } + // without gpr registers we can do nothing + if (!current_xml_filename) { + return -1; + } =20 - const char *xml_filename =3D NULL; - const char *xml_content =3D NULL; - const char *name =3D NULL; - int i; + // 2. add group for gpr registers + mcd_reg_group_st gprregs =3D { .name =3D "GPR Registers", .id =3D *cur= rent_group_id }; + g_array_append_vals(reggroups, (gconstpointer)&gprregs, 1); + *current_group_id =3D *current_group_id + 1; =20 - // 1. check out the core xml file - xml_filename =3D cc->gdb_core_xml_file; + // 3. parse xml + xml_content =3D xml_builtin[i][1]; + parse_reg_xml(xml_content, strlen(xml_content), registers); + return 0; +} =20 - for (i =3D 0; ; i++) { - name =3D xml_builtin[i][0]; - if (!name || (strncmp(name, xml_filename, strlen(xml_filen= ame)) =3D=3D 0 && strlen(name) =3D=3D strlen(xml_filename))) +int mcd_arm_parse_general_xml_files(CPUState *cpu, GArray* reggroups, GArr= ay* registers, int* current_group_id) { + const char *xml_filename =3D NULL; + const char *current_xml_filename =3D NULL; + const char *xml_content =3D NULL; + int i =3D 0; + + // iterate over all gdb xml files=20 + GDBRegisterState *r; + for (r =3D cpu->gdb_regs; r; r =3D r->next) { + xml_filename =3D r->xml; + xml_content =3D NULL; + + // 1. get xml content + xml_content =3D arm_mcd_get_dynamic_xml(cpu, xml_filename); + if (xml_content) { + if (strcmp(xml_filename, "system-registers.xml")=3D=3D0) { + // these are the coprocessor register + mcd_reg_group_st corprocessorregs =3D { .name =3D "CP15 Re= gisters", .id =3D *current_group_id }; + g_array_append_vals(reggroups, (gconstpointer)&corprocesso= rregs, 1); + *current_group_id =3D *current_group_id + 1; + } =20 + } + else { + // its not a coprocessor xml -> it is a static xml file + for (i =3D 0; ; i++) { + current_xml_filename =3D xml_builtin[i][0]; + if (!current_xml_filename || (strncmp(current_xml_filename= , xml_filename, strlen(xml_filename)) =3D=3D 0 + && strlen(current_xml_filename) =3D=3D strlen(xml_file= name))) break; } - // without gpr registers we can do nothing - assert(name); - // add group for gpr registers - current_group_id =3D 1; - mcd_reg_group_st group1 =3D { .name =3D "GPR Registers", .id =3D c= urrent_group_id }; - g_array_append_vals(mcdserver_state.reggroups, (gconstpointer)&gro= up1, 1); - - // parse xml - xml_content =3D xml_builtin[i][1]; - parse_reg_xml(xml_content, strlen(xml_content)); - - // 2. iterate over all other xml files - GDBRegisterState *r; - for (r =3D cpu->gdb_regs; r; r =3D r->next) { - xml_filename =3D r->xml; - xml_content =3D NULL; - - // first, check if this is a coprocessor xml - - // funciton call - xml_content =3D arm_mcd_get_dynamic_xml(cpu, xml_filename); - if (xml_content) { - if (strcmp(xml_filename, "system-registers.xml")=3D=3D0) { - //these are the coprocessor register - current_group_id =3D 2; - mcd_reg_group_st group2 =3D { .name =3D "CP15 Register= s", .id =3D current_group_id }; - g_array_append_vals(mcdserver_state.reggroups, (gconst= pointer)&group2, 1); - } - =20 + if (current_xml_filename) { + xml_content =3D xml_builtin[i][1]; } else { - // its not a coprocessor xml -> it is a static xml file - for (i =3D 0; ; i++) { - name =3D xml_builtin[i][0]; - if (!name || (strncmp(name, xml_filename, strlen(xml_f= ilename)) =3D=3D 0 && strlen(name) =3D=3D strlen(xml_filename))) - break; - } - if (name) { - xml_content =3D xml_builtin[i][1]; - } - else { - printf("no data found for %s\n", xml_filename); - continue; - } + printf("no data found for %s\n", xml_filename); + continue; } + } + // 2. parse xml + parse_reg_xml(xml_content, strlen(xml_content), registers); + } + return 0; +} =20 - // parse xml - parse_reg_xml(xml_content, strlen(xml_content)); +int mcd_arm_get_additional_register_info(GArray* reggroups, GArray* regist= ers) { + GList *register_numbers =3D NULL; + mcd_reg_st *current_register; + int i =3D 0; + int id_neg_offset =3D 0; + int effective_id =3D 0; + + // iterate over all registers + for (i =3D 0; i < registers->len; i++) { + current_register =3D &(g_array_index(registers, mcd_reg_st, i)); + // 1. ad the id + if (current_register->id) { + // id is already in place + // NOTE: qemu doesn't emulate the FPA regs (so we are missing = the indices 16 to 24) + int used_id =3D current_register->id; + register_numbers =3D g_list_append(register_numbers, &used_id); + id_neg_offset ++; } - // go over the register array and collect all additional data - mcd_reg_st *current_register; - int id_neg_offset =3D 0; - int effective_id; - for (i =3D 0; i < mcdserver_state.registers->len; i++) { - current_register =3D &(g_array_index(mcdserver_state.registers= , mcd_reg_st, i)); - // ad an id handle - if (current_register->id) { - // id is already in place - //FIXME: we are missing 10 registers (likely the FPA regs = or sth) - int used_id =3D current_register->id; - register_numbers =3D g_list_append(register_numbers, &used= _id); - id_neg_offset ++; - } - else { - effective_id =3D i - id_neg_offset; - if (g_list_find_custom(register_numbers, &effective_id, (G= CompareFunc)int_cmp)!=3DNULL) { - id_neg_offset --; - } - current_register->id =3D i - id_neg_offset; - } - // sort into correct reg_group and according mem_space - if (strcmp(current_register->group, "cp_regs")=3D=3D0) { - current_register->mcd_reg_group_id =3D 2; - current_register->mcd_mem_space_id =3D 6; - // get info for opcode - } - else { - // gpr register - current_register->mcd_reg_group_id =3D 1; - current_register->mcd_mem_space_id =3D 5; + else { + effective_id =3D i - id_neg_offset; + if (g_list_find_custom(register_numbers, &effective_id, (GComp= areFunc)int_cmp)!=3DNULL) { + id_neg_offset --; } + current_register->id =3D i - id_neg_offset; + } + // 2. add mcd_reg_group_id and mcd_mem_space_id + if (strcmp(current_register->group, "cp_regs")=3D=3D0) { + // coprocessor registers + current_register->mcd_reg_group_id =3D 2; + current_register->mcd_mem_space_id =3D 6; + // TODO: get info for opcode + } + else { + // gpr register + current_register->mcd_reg_group_id =3D 1; + current_register->mcd_mem_space_id =3D 5; + } + } + g_list_free(register_numbers); + return 0; +} + +void handle_open_core(GArray *params, void *user_ctx) { + // get the cpu whith the given id + uint32_t cpu_id =3D get_param(params, 0)->cpu_id; + CPUState *cpu =3D mcd_get_cpu(cpu_id); + CPUClass *cc =3D CPU_GET_CLASS(cpu); + gchar *arch =3D cc->gdb_arch_name(cpu); + int return_value =3D 0; + + // prepare data strucutures + GArray* memspaces =3D g_array_new(false, true, sizeof(mcd_mem_space_st= )); + GArray* reggroups =3D g_array_new(false, true, sizeof(mcd_reg_group_st= )); + GArray* registers =3D g_array_new(false, true, sizeof(mcd_reg_st)); + =20 + if (strcmp(arch, "arm")=3D=3D0) { + // TODO: make group and memspace ids dynamic + int current_group_id =3D 1; + // 1. store mem spaces + return_value =3D mcd_arm_store_mem_spaces(cpu, memspaces); + if (return_value!=3D0) assert(0); + // 2. parse core xml + return_value =3D mcd_arm_parse_core_xml_file(cc, reggroups, regist= ers, ¤t_group_id); + if (return_value!=3D0) assert(0); + // 3. parse other xmls + return_value =3D mcd_arm_parse_general_xml_files(cpu, reggroups, r= egisters, ¤t_group_id); + if (return_value!=3D0) assert(0); + // 4. add additional data the the regs from the xmls + return_value =3D mcd_arm_get_additional_register_info(reggroups, r= egisters); + if (return_value!=3D0) assert(0); + // 5. store all found data + if (g_list_nth(mcdserver_state.all_memspaces, cpu_id)) { + GList* memspaces_ptr =3D g_list_nth(mcdserver_state.all_memspa= ces, cpu_id); + memspaces_ptr->data =3D memspaces; + } + else { + mcdserver_state.all_memspaces =3D g_list_insert(mcdserver_stat= e.all_memspaces, memspaces, cpu_id); + } + if (g_list_nth(mcdserver_state.all_reggroups, cpu_id)) { + GList* reggroups_ptr =3D g_list_nth(mcdserver_state.all_reggro= ups, cpu_id); + reggroups_ptr->data =3D reggroups; + } + else { + mcdserver_state.all_reggroups =3D g_list_insert(mcdserver_stat= e.all_reggroups, reggroups, cpu_id); + } + if (g_list_nth(mcdserver_state.all_registers, cpu_id)) { + GList* registers_ptr =3D g_list_nth(mcdserver_state.all_regist= ers, cpu_id); + registers_ptr->data =3D registers; + } + else { + mcdserver_state.all_registers =3D g_list_insert(mcdserver_stat= e.all_registers, registers, cpu_id); } - // free memory - g_list_free(register_numbers); } else { // we don't support other architectures @@ -1170,30 +1293,77 @@ void handle_open_core(GArray *params, void *user_ct= x) { g_free(arch); } =20 -void handle_query_reset(GArray *params, void *user_ctx) { +void handle_query_reset_f(GArray *params, void *user_ctx) { // resetting has to be done over a monitor (look ar Rcmd) so we tell M= CD that we can reset but this still need to be implemented - // we only support one reset over this monitor and that would be a ful= ly "system_restart" - mcd_put_packet("nr=3D\"3\",info=3D\"0,full_system_reset;1,gpr_reset;2,= memory_reset;\""); + // we only support one reset over this monitor and that would be a ful= l "system_restart" + // reset options are the same for every cpu! + =20 + // 1. check length + int nb_resets =3D mcdserver_state.resets->len; + if (nb_resets =3D=3D 1) { + // indicates this is the last packet + g_string_printf(mcdserver_state.str_buf, "0!"); + } + else { + g_string_printf(mcdserver_state.str_buf, "1!"); + } + // 2. send data + mcd_reset_st reset =3D g_array_index(mcdserver_state.resets, mcd_reset= _st, 0); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%s.%s=3D%d.", TC= P_ARGUMENT_NAME, reset.name, TCP_ARGUMENT_ID, reset.id); + mcd_put_strbuf(); + // TODO: we still need to implement the gpr and memory reset here! +} + +void handle_query_reset_c(GArray *params, void *user_ctx) { + // reset options are the same for every cpu! + int query_index =3D get_param(params, 0)->query_handle; + =20 + // 1. check weather this was the last mem space + int nb_groups =3D mcdserver_state.resets->len; + if (query_index+1 =3D=3D nb_groups) { + // indicates this is the last packet + g_string_printf(mcdserver_state.str_buf, "0!"); + } + else { + g_string_printf(mcdserver_state.str_buf, "%d!", query_index+1); + } + + // 2. send data + mcd_reset_st reset =3D g_array_index(mcdserver_state.resets, mcd_reset= _st, query_index); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%s.%s=3D%d.", TC= P_ARGUMENT_NAME, reset.name, TCP_ARGUMENT_ID, reset.id); + mcd_put_strbuf(); // TODO: we still need to implement the gpr and memory reset here! } =20 -void handle_detach(GArray *params, void *user_ctx) { +void handle_close_core(GArray *params, void *user_ctx) { + // free memory for correct core + uint32_t cpu_id =3D get_param(params, 0)->cpu_id; + GArray* memspaces =3D g_list_nth_data(mcdserver_state.all_memspaces, c= pu_id); + g_array_free(memspaces, TRUE); + GArray* reggroups =3D g_list_nth_data(mcdserver_state.all_reggroups, c= pu_id); + g_array_free(reggroups, TRUE); + GArray* registers =3D g_list_nth_data(mcdserver_state.all_registers, c= pu_id); + g_array_free(registers, TRUE); +} + +void handle_close_server(GArray *params, void *user_ctx) { uint32_t pid =3D 1; MCDProcess *process =3D mcd_get_process(pid); =20 - // 1. cleanup - // gdb_process_breakpoint_remove_all(process); + // 1. free memory + // TODO: do this only if there are no processes attached anymore! + g_list_free(mcdserver_state.all_memspaces); + g_list_free(mcdserver_state.all_reggroups); + g_list_free(mcdserver_state.all_registers); + g_array_free(mcdserver_state.resets, TRUE); =20 // 2. detach process->attached =3D false; =20 - // reset current cpus - // TODO: if we don't use c_cpu we can delete this - // this also checks to only reset THIS process we also probably don't = need this since we only got one process! + // 3. reset process if (pid =3D=3D mcd_get_cpu_pid(mcdserver_state.c_cpu)) { mcdserver_state.c_cpu =3D mcd_first_attached_cpu(); } - if (!mcdserver_state.c_cpu) { /* No more process attached */ mcd_disable_syscalls(); @@ -1202,14 +1372,10 @@ void handle_detach(GArray *params, void *user_ctx) { } =20 void handle_query_trigger(GArray *params, void *user_ctx) { - // set the type, option and action bitmask and send it - - uint32_t type =3D (MCD_TRIG_TYPE_IP | MCD_TRIG_TYPE_READ | MCD_TRIG_TY= PE_WRITE | MCD_TRIG_TYPE_RW); - uint32_t option =3D (MCD_TRIG_OPT_DATA_IS_CONDITION); - uint32_t action =3D (MCD_TRIG_ACTION_DBG_DEBUG); - uint32_t nr_trigger =3D 4; - - g_string_printf(mcdserver_state.str_buf, "nr=3D\"%d\",info=3D\"%d;%d;%= d;\"", nr_trigger, type, option, action); + mcd_trigger_st trigger =3D mcdserver_state.trigger; + g_string_printf(mcdserver_state.str_buf, "%s=3D%d.%s=3D%d.%s=3D%d.%s= =3D%d.", + TCP_ARGUMENT_AMOUNT_TRIGGER, trigger.nr_trigger, TCP_ARGUMENT_TYP= E, trigger.type, + TCP_ARGUMENT_OPTION, trigger.option, TCP_ARGUMENT_ACTION, trigger.= action); mcd_put_strbuf(); } =20 @@ -1221,8 +1387,13 @@ void mcd_continue(void) } =20 void handle_query_mem_spaces_f(GArray *params, void *user_ctx) { - // send the first mem space - int nb_groups =3D mcdserver_state.memspaces->len; + // 1. get correct memspaces and set the query_cpu + uint32_t cpu_id =3D get_param(params, 0)->cpu_id; + mcdserver_state.query_cpu_id =3D cpu_id; + GArray* memspaces =3D g_list_nth_data(mcdserver_state.all_memspaces, c= pu_id); + + // 2. check length + int nb_groups =3D memspaces->len; if (nb_groups =3D=3D 1) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1230,20 +1401,26 @@ void handle_query_mem_spaces_f(GArray *params, void= *user_ctx) { else { g_string_printf(mcdserver_state.str_buf, "1!"); } - mcd_mem_space_st space =3D g_array_index(mcdserver_state.memspaces, mc= d_mem_space_st, 0); - g_string_append_printf(mcdserver_state.str_buf, "name=3D%s.id=3D%d.typ= e=3D%d.bpm=3D%d.i=3D%d.e=3D%d.min=3D%ld.max=3D%ld.sao=3D%d.", - space.name, space.id, space.type, space.bits_per_mau, space.invari= ance, space.endian, - space.min_addr, space.max_addr, space.supported_access_options); + + // 3. send data + mcd_mem_space_st space =3D g_array_index(memspaces, mcd_mem_space_st, = 0); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%s.%s=3D%d.%s=3D= %d.%s=3D%d.%s=3D%d.%s=3D%d.%s=3D%ld.%s=3D%ld.%s=3D%d.", + TCP_ARGUMENT_NAME, space.name, TCP_ARGUMENT_ID, space.id, TCP_ARGU= MENT_TYPE, space.type, + TCP_ARGUMENT_BITS_PER_MAU, space.bits_per_mau, TCP_ARGUMENT_INVARI= ANCE, space.invariance, TCP_ARGUMENT_ENDIAN, space.endian, + TCP_ARGUMENT_MIN, space.min_addr, TCP_ARGUMENT_MAX, space.max_addr, + TCP_ARGUMENT_SUPPORTED_ACCESS_OPTIONS, space.supported_access_opti= ons); mcd_put_strbuf(); } =20 void handle_query_mem_spaces_c(GArray *params, void *user_ctx) { // this funcitons send all mem spaces except for the first - // 1. get parameter + // 1. get parameter and memspace int query_index =3D get_param(params, 0)->query_handle; + uint32_t cpu_id =3D mcdserver_state.query_cpu_id; + GArray* memspaces =3D g_list_nth_data(mcdserver_state.all_memspaces, c= pu_id); =20 // 2. check weather this was the last mem space - int nb_groups =3D mcdserver_state.memspaces->len; + int nb_groups =3D memspaces->len; if (query_index+1 =3D=3D nb_groups) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1253,16 +1430,23 @@ void handle_query_mem_spaces_c(GArray *params, void= *user_ctx) { } =20 // 3. send the correct memspace - mcd_mem_space_st space =3D g_array_index(mcdserver_state.memspaces, mc= d_mem_space_st, query_index); - g_string_append_printf(mcdserver_state.str_buf, "name=3D%s.id=3D%d.typ= e=3D%d.bpm=3D%d.i=3D%d.e=3D%d.min=3D%ld.max=3D%ld.sao=3D%d.", - space.name, space.id, space.type, space.bits_per_mau, space.invari= ance, space.endian, - space.min_addr, space.max_addr, space.supported_access_options); + mcd_mem_space_st space =3D g_array_index(memspaces, mcd_mem_space_st, = query_index); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%s.%s=3D%d.%s=3D= %d.%s=3D%d.%s=3D%d.%s=3D%d.%s=3D%ld.%s=3D%ld.%s=3D%d.", + TCP_ARGUMENT_NAME, space.name, TCP_ARGUMENT_ID, space.id, TCP_ARGU= MENT_TYPE, space.type, + TCP_ARGUMENT_BITS_PER_MAU, space.bits_per_mau, TCP_ARGUMENT_INVARI= ANCE, space.invariance, TCP_ARGUMENT_ENDIAN, space.endian, + TCP_ARGUMENT_MIN, space.min_addr, TCP_ARGUMENT_MAX, space.max_addr, + TCP_ARGUMENT_SUPPORTED_ACCESS_OPTIONS, space.supported_access_opti= ons); mcd_put_strbuf(); } =20 void handle_query_reg_groups_f(GArray *params, void *user_ctx) { - // send the first reg group - int nb_groups =3D mcdserver_state.reggroups->len; + // 1. get correct reggroups and set the query_cpu + uint32_t cpu_id =3D get_param(params, 0)->cpu_id; + mcdserver_state.query_cpu_id =3D cpu_id; + GArray* reggroups =3D g_list_nth_data(mcdserver_state.all_reggroups, c= pu_id); + + // 2. check length + int nb_groups =3D reggroups->len; if (nb_groups =3D=3D 1) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1270,18 +1454,21 @@ void handle_query_reg_groups_f(GArray *params, void= *user_ctx) { else { g_string_printf(mcdserver_state.str_buf, "1!"); } - mcd_reg_group_st group =3D g_array_index(mcdserver_state.reggroups, mc= d_reg_group_st, 0); - g_string_append_printf(mcdserver_state.str_buf, "id=3D%d.name=3D%s.", = group.id, group.name); + // 3. send data + mcd_reg_group_st group =3D g_array_index(reggroups, mcd_reg_group_st, = 0); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%d.%s=3D%s.", TC= P_ARGUMENT_ID, group.id, TCP_ARGUMENT_NAME, group.name); mcd_put_strbuf(); } =20 void handle_query_reg_groups_c(GArray *params, void *user_ctx) { // this funcitons send all reg groups except for the first - // 1. get parameter + // 1. get parameter and memspace int query_index =3D get_param(params, 0)->query_handle; + uint32_t cpu_id =3D mcdserver_state.query_cpu_id; + GArray* reggroups =3D g_list_nth_data(mcdserver_state.all_reggroups, c= pu_id); =20 // 2. check weather this was the last reg group - int nb_groups =3D mcdserver_state.reggroups->len; + int nb_groups =3D reggroups->len; if (query_index+1 =3D=3D nb_groups) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1291,14 +1478,19 @@ void handle_query_reg_groups_c(GArray *params, void= *user_ctx) { } =20 // 3. send the correct reggroup - mcd_reg_group_st group =3D g_array_index(mcdserver_state.reggroups, mc= d_reg_group_st, query_index); - g_string_append_printf(mcdserver_state.str_buf, "id=3D%d.name=3D%s.", = group.id, group.name); + mcd_reg_group_st group =3D g_array_index(reggroups, mcd_reg_group_st, = query_index); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%d.%s=3D%s.", TC= P_ARGUMENT_ID, group.id, TCP_ARGUMENT_NAME, group.name); mcd_put_strbuf(); } =20 void handle_query_regs_f(GArray *params, void *user_ctx) { - // send the first register - int nb_regs =3D mcdserver_state.registers->len; + // 1. get correct registers and set the query_cpu + uint32_t cpu_id =3D get_param(params, 0)->cpu_id; + mcdserver_state.query_cpu_id =3D cpu_id; + GArray* registers =3D g_list_nth_data(mcdserver_state.all_registers, c= pu_id); + + // 2. check length + int nb_regs =3D registers->len; if (nb_regs =3D=3D 1) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1306,20 +1498,24 @@ void handle_query_regs_f(GArray *params, void *user= _ctx) { else { g_string_printf(mcdserver_state.str_buf, "1!"); } - mcd_reg_st my_register =3D g_array_index(mcdserver_state.registers, mc= d_reg_st, 0); - g_string_append_printf(mcdserver_state.str_buf, "id=3D%d.name=3D%s.siz= e=3D%d.reggroupid=3D%d.memspaceid=3D%d.type=3D%d.thread=3D%d.", - my_register.id, my_register.name, my_register.bitsize, my_register= .mcd_reg_group_id, - my_register.mcd_mem_space_id, my_register.mcd_reg_type, my_registe= r.mcd_hw_thread_id); + // 3. send data + mcd_reg_st my_register =3D g_array_index(registers, mcd_reg_st, 0); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%d.%s=3D%s.%s=3D= %d.%s=3D%d.%s=3D%d.%s=3D%d.%s=3D%d.", + TCP_ARGUMENT_ID, my_register.id, TCP_ARGUMENT_NAME, my_register.n= ame, TCP_ARGUMENT_SIZE, my_register.bitsize, + TCP_ARGUMENT_REGGROUPID, my_register.mcd_reg_group_id, TCP_ARGUMEN= T_MEMSPACEID, my_register.mcd_mem_space_id, + TCP_ARGUMENT_TYPE, my_register.mcd_reg_type, TCP_ARGUMENT_THREAD, = my_register.mcd_hw_thread_id); mcd_put_strbuf(); } =20 void handle_query_regs_c(GArray *params, void *user_ctx) { - // this funcitons send all registers except for the first - // 1. get parameter + // this funcitons send all reg groups except for the first + // 1. get parameter and registers int query_index =3D get_param(params, 0)->query_handle; + uint32_t cpu_id =3D mcdserver_state.query_cpu_id; + GArray* registers =3D g_list_nth_data(mcdserver_state.all_registers, c= pu_id); =20 // 2. check weather this was the last register - int nb_regs =3D mcdserver_state.registers->len; + int nb_regs =3D registers->len; if (query_index+1 =3D=3D nb_regs) { // indicates this is the last packet g_string_printf(mcdserver_state.str_buf, "0!"); @@ -1329,9 +1525,10 @@ void handle_query_regs_c(GArray *params, void *user_= ctx) { } =20 // 3. send the correct register - mcd_reg_st my_register =3D g_array_index(mcdserver_state.registers, mc= d_reg_st, query_index); - g_string_append_printf(mcdserver_state.str_buf, "id=3D%d.name=3D%s.siz= e=3D%d.reggroupid=3D%d.memspaceid=3D%d.type=3D%d.thread=3D%d.", - my_register.id, my_register.name, my_register.bitsize, my_register= .mcd_reg_group_id, - my_register.mcd_mem_space_id, my_register.mcd_reg_type, my_registe= r.mcd_hw_thread_id); + mcd_reg_st my_register =3D g_array_index(registers, mcd_reg_st, query_= index); + g_string_append_printf(mcdserver_state.str_buf, "%s=3D%d.%s=3D%s.%s=3D= %d.%s=3D%d.%s=3D%d.%s=3D%d.%s=3D%d.", + TCP_ARGUMENT_ID, my_register.id, TCP_ARGUMENT_NAME, my_register.n= ame, TCP_ARGUMENT_SIZE, my_register.bitsize, + TCP_ARGUMENT_REGGROUPID, my_register.mcd_reg_group_id, TCP_ARGUMEN= T_MEMSPACEID, my_register.mcd_mem_space_id, + TCP_ARGUMENT_TYPE, my_register.mcd_reg_type, TCP_ARGUMENT_THREAD, = my_register.mcd_hw_thread_id); mcd_put_strbuf(); } --=20 2.34.1