From nobody Wed Nov 27 02:28:20 2024 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 1701983251095921.307315731751; Thu, 7 Dec 2023 13:07:31 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rBLYA-0002o8-7W; Thu, 07 Dec 2023 16:04:50 -0500 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 1rBLY1-0002kC-61 for qemu-devel@nongnu.org; Thu, 07 Dec 2023 16:04:41 -0500 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 1rBLXw-0005oL-5n for qemu-devel@nongnu.org; Thu, 07 Dec 2023 16:04:39 -0500 Received: (qmail 10418 invoked by uid 484); 7 Dec 2023 21:04:15 -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 ; 7 Dec 2023 21:04:14 -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.077406 secs); 07 Dec 2023 21:04:15 -0000 From: Nicolas Eder To: qemu-devel@nongnu.org Cc: "Nicolas Eder" , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , "Christian Boenig" , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v4 10/17] mcdstub: open and close server funcitons added Date: Thu, 7 Dec 2023 22:03:51 +0100 Message-Id: <20231207210358.7409-11-nicolas.eder@lauterbach.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231207210358.7409-1-nicolas.eder@lauterbach.com> References: <20231207210358.7409-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, T_SCC_BODY_TEXT_LINE=-0.01 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: 1701983253078100002 Content-Type: text/plain; charset="utf-8" --- debug/mcdstub/mcdstub.c | 300 ++++++++++++++++++++++++++++------------ 1 file changed, 215 insertions(+), 85 deletions(-) diff --git a/debug/mcdstub/mcdstub.c b/debug/mcdstub/mcdstub.c index f97bccf409..d59c4ac078 100644 --- a/debug/mcdstub/mcdstub.c +++ b/debug/mcdstub/mcdstub.c @@ -65,6 +65,91 @@ static void mcd_sigterm_handler(int signal) } #endif =20 +/** + * mcd_get_process() - Returns the process of the provided pid. + * + * @pid: The process ID. + */ +static MCDProcess *mcd_get_process(uint32_t pid) +{ + int i; + + if (!pid) { + /* 0 means any process, we take the first one */ + return &mcdserver_state.processes[0]; + } + + for (i =3D 0; i < mcdserver_state.process_num; i++) { + if (mcdserver_state.processes[i].pid =3D=3D pid) { + return &mcdserver_state.processes[i]; + } + } + + return NULL; +} + +/** + * mcd_get_cpu_pid() - Returns the process ID of the provided CPU. + * + * @cpu: The CPU state. + */ +static uint32_t mcd_get_cpu_pid(CPUState *cpu) +{ + if (cpu->cluster_index =3D=3D UNASSIGNED_CLUSTER_INDEX) { + /* Return the default process' PID */ + int index =3D mcdserver_state.process_num - 1; + return mcdserver_state.processes[index].pid; + } + return cpu->cluster_index + 1; +} + +/** + * mcd_get_cpu_process() - Returns the process of the provided CPU. + * + * @cpu: The CPU state. + */ +static MCDProcess *mcd_get_cpu_process(CPUState *cpu) +{ + return mcd_get_process(mcd_get_cpu_pid(cpu)); +} + +/** + * mcd_next_attached_cpu() - Returns the first CPU with an attached process + * starting after the + * provided cpu. + * + * @cpu: The CPU to start from. + */ +static CPUState *mcd_next_attached_cpu(CPUState *cpu) +{ + cpu =3D CPU_NEXT(cpu); + + while (cpu) { + if (mcd_get_cpu_process(cpu)->attached) { + break; + } + + cpu =3D CPU_NEXT(cpu); + } + + return cpu; +} + +/** + * mcd_first_attached_cpu() - Returns the first CPU with an attached proce= ss. + */ +static CPUState *mcd_first_attached_cpu(void) +{ + CPUState *cpu =3D first_cpu; + MCDProcess *process =3D mcd_get_cpu_process(cpu); + + if (!process->attached) { + return mcd_next_attached_cpu(cpu); + } + + return cpu; +} + /** * mcd_vm_state_change() - Handles a state change of the QEMU VM. * @@ -284,6 +369,117 @@ static void run_cmd_parser(const char *data, const MC= DCmdParseEntry *cmd) } } =20 +/** + * init_resets() - Initializes the resets info. + * + * This function currently only adds all theoretical possible resets to the + * resets GArray. None of the resets work at the moment. The resets are: + * "full_system_reset", "gpr_reset" and "memory_reset". + * @resets: GArray with possible resets. + */ +static 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; +} + +/** + * init_trigger() - Initializes the trigger info. + * + * This function adds the types of trigger, their possible options and act= ions + * to the trigger struct. + * @trigger: Struct with all trigger info. + */ +static int init_trigger(mcd_trigger_into_st *trigger) +{ + snprintf(trigger->type, sizeof(trigger->type), + "%d,%d,%d,%d", MCD_BREAKPOINT_HW, MCD_BREAKPOINT_READ, + MCD_BREAKPOINT_WRITE, MCD_BREAKPOINT_RW); + snprintf(trigger->option, sizeof(trigger->option), + "%s", MCD_TRIG_OPT_VALUE); + snprintf(trigger->action, sizeof(trigger->action), + "%s", MCD_TRIG_ACT_BREAK); + /* there can be 16 breakpoints and 16 watchpoints each */ + trigger->nr_trigger =3D 16; + return 0; +} + +/** + * handle_open_server() - Handler for opening the MCD server. + * + * This is the first function that gets called from the MCD Shared Library. + * It initializes core indepent data with the :c:func:`init_resets` and + * \reg init_trigger functions. It also send the TCP_HANDSHAKE_SUCCESS + * packet back to the library to confirm the mcdstub is ready for further + * communication. + * @params: GArray with all TCP packet parameters. + */ +static void handle_open_server(GArray *params, void *user_ctx) +{ + /* initialize 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 !=3D 0) { + g_assert_not_reached(); + } + return_value =3D init_trigger(&mcdserver_state.trigger); + if (return_value !=3D 0) { + g_assert_not_reached(); + } + + mcd_put_packet(TCP_HANDSHAKE_SUCCESS); +} + +/** + * mcd_vm_start() - Starts all CPUs with the vm_start function. + */ +static void mcd_vm_start(void) +{ + if (!runstate_needs_reset() && !runstate_is_running()) { + vm_start(); + } +} + +/** + * handle_close_server() - Handler for closing the MCD server. + * + * This function detaches the debugger (process) and frees up memory. + * Then it start the QEMU VM with :c:func:`mcd_vm_start`. + * @params: GArray with all TCP packet parameters. + */ +static void handle_close_server(GArray *params, void *user_ctx) +{ + uint32_t pid =3D 1; + MCDProcess *process =3D mcd_get_process(pid); + + /* + * 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); + + /* 2. detach */ + process->attached =3D false; + + /* 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 processes attached */ + mcd_vm_start(); + } +} + /** * mcd_handle_packet() - Evaluates the type of received packet and chooses= the * correct handler. @@ -302,6 +498,25 @@ static int mcd_handle_packet(const char *line_buf) const MCDCmdParseEntry *cmd_parser =3D NULL; =20 switch (line_buf[0]) { + case TCP_CHAR_OPEN_SERVER: + { + static MCDCmdParseEntry open_server_cmd_desc =3D { + .handler =3D handle_open_server, + }; + open_server_cmd_desc.cmd =3D (char[2]) { TCP_CHAR_OPEN_SERVER,= '\0' }; + cmd_parser =3D &open_server_cmd_desc; + } + break; + case TCP_CHAR_CLOSE_SERVER: + { + static MCDCmdParseEntry close_server_cmd_desc =3D { + .handler =3D handle_close_server, + }; + close_server_cmd_desc.cmd =3D + (char[2]) { TCP_CHAR_CLOSE_SERVER, '\0' }; + cmd_parser =3D &close_server_cmd_desc; + } + break; default: /* command not supported */ mcd_put_packet(""); @@ -422,91 +637,6 @@ static void mcd_chr_receive(void *opaque, const uint8_= t *buf, int size) } } =20 -/** - * mcd_get_process() - Returns the process of the provided pid. - * - * @pid: The process ID. - */ -static MCDProcess *mcd_get_process(uint32_t pid) -{ - int i; - - if (!pid) { - /* 0 means any process, we take the first one */ - return &mcdserver_state.processes[0]; - } - - for (i =3D 0; i < mcdserver_state.process_num; i++) { - if (mcdserver_state.processes[i].pid =3D=3D pid) { - return &mcdserver_state.processes[i]; - } - } - - return NULL; -} - -/** - * mcd_get_cpu_pid() - Returns the process ID of the provided CPU. - * - * @cpu: The CPU state. - */ -static uint32_t mcd_get_cpu_pid(CPUState *cpu) -{ - if (cpu->cluster_index =3D=3D UNASSIGNED_CLUSTER_INDEX) { - /* Return the default process' PID */ - int index =3D mcdserver_state.process_num - 1; - return mcdserver_state.processes[index].pid; - } - return cpu->cluster_index + 1; -} - -/** - * mcd_get_cpu_process() - Returns the process of the provided CPU. - * - * @cpu: The CPU state. - */ -static MCDProcess *mcd_get_cpu_process(CPUState *cpu) -{ - return mcd_get_process(mcd_get_cpu_pid(cpu)); -} - -/** - * mcd_next_attached_cpu() - Returns the first CPU with an attached process - * starting after the - * provided cpu. - * - * @cpu: The CPU to start from. - */ -static CPUState *mcd_next_attached_cpu(CPUState *cpu) -{ - cpu =3D CPU_NEXT(cpu); - - while (cpu) { - if (mcd_get_cpu_process(cpu)->attached) { - break; - } - - cpu =3D CPU_NEXT(cpu); - } - - return cpu; -} - -/** - * mcd_first_attached_cpu() - Returns the first CPU with an attached proce= ss. - */ -static CPUState *mcd_first_attached_cpu(void) -{ - CPUState *cpu =3D first_cpu; - MCDProcess *process =3D mcd_get_cpu_process(cpu); - - if (!process->attached) { - return mcd_next_attached_cpu(cpu); - } - - return cpu; -} - /** * mcd_chr_event() - Handles a TCP client connect. * --=20 2.34.1