From: Nicolas Eder <nicolas.eder@lauterbach.com>
To: qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Christian Boenig" <christian.boenig@lauterbach.com>,
"Nicolas Eder" <nicolas.eder@lauterbach.com>
Subject: [PATCH v5 10/18] mcdstub: open and close server functions added
Date: Wed, 20 Dec 2023 17:25:47 +0100 [thread overview]
Message-ID: <20231220162555.19545-11-nicolas.eder@lauterbach.com> (raw)
In-Reply-To: <20231220162555.19545-1-nicolas.eder@lauterbach.com>
---
debug/mcdstub/mcdstub.c | 299 ++++++++++++++++++++++++++++------------
1 file changed, 214 insertions(+), 85 deletions(-)
diff --git a/debug/mcdstub/mcdstub.c b/debug/mcdstub/mcdstub.c
index 642f3c2826..45daa38689 100644
--- a/debug/mcdstub/mcdstub.c
+++ b/debug/mcdstub/mcdstub.c
@@ -65,6 +65,91 @@ static void mcd_sigterm_handler(int signal)
}
#endif
+/**
+ * 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 = 0; i < mcdserver_state.process_num; i++) {
+ if (mcdserver_state.processes[i].pid == 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 == UNASSIGNED_CLUSTER_INDEX) {
+ /* Return the default process' PID */
+ int index = 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 = CPU_NEXT(cpu);
+
+ while (cpu) {
+ if (mcd_get_cpu_process(cpu)->attached) {
+ break;
+ }
+
+ cpu = CPU_NEXT(cpu);
+ }
+
+ return cpu;
+}
+
+/**
+ * mcd_first_attached_cpu() - Returns the first CPU with an attached process.
+ */
+static CPUState *mcd_first_attached_cpu(void)
+{
+ CPUState *cpu = first_cpu;
+ MCDProcess *process = 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 MCDCmdParseEntry *cmd)
}
}
+/**
+ * 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 = { .id = 0, .name = RESET_SYSTEM};
+ mcd_reset_st gpr_reset = { .id = 1, .name = RESET_GPR};
+ mcd_reset_st memory_reset = { .id = 2, .name = 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 actions
+ * 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 = 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 = 0;
+ mcdserver_state.resets = g_array_new(false, true, sizeof(mcd_reset_st));
+ return_value = init_resets(mcdserver_state.resets);
+ if (return_value != 0) {
+ g_assert_not_reached();
+ }
+ return_value = init_trigger(&mcdserver_state.trigger);
+ if (return_value != 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 = 1;
+ MCDProcess *process = 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 = false;
+
+ /* 3. reset process */
+ if (pid == mcd_get_cpu_pid(mcdserver_state.c_cpu)) {
+ mcdserver_state.c_cpu = 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,24 @@ static int mcd_handle_packet(const char *line_buf)
const MCDCmdParseEntry *cmd_parser = NULL;
switch (line_buf[0]) {
+ case TCP_CHAR_OPEN_SERVER:
+ {
+ static MCDCmdParseEntry open_server_cmd_desc = {
+ .handler = handle_open_server,
+ .cmd = {TCP_CHAR_OPEN_SERVER, '\0'},
+ };
+ cmd_parser = &open_server_cmd_desc;
+ }
+ break;
+ case TCP_CHAR_CLOSE_SERVER:
+ {
+ static MCDCmdParseEntry close_server_cmd_desc = {
+ .handler = handle_close_server,
+ .cmd = {TCP_CHAR_CLOSE_SERVER, '\0'},
+ };
+ cmd_parser = &close_server_cmd_desc;
+ }
+ break;
default:
/* command not supported */
mcd_put_packet("");
@@ -422,91 +636,6 @@ static void mcd_chr_receive(void *opaque, const uint8_t *buf, int size)
}
}
-/**
- * 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 = 0; i < mcdserver_state.process_num; i++) {
- if (mcdserver_state.processes[i].pid == 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 == UNASSIGNED_CLUSTER_INDEX) {
- /* Return the default process' PID */
- int index = 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 = CPU_NEXT(cpu);
-
- while (cpu) {
- if (mcd_get_cpu_process(cpu)->attached) {
- break;
- }
-
- cpu = CPU_NEXT(cpu);
- }
-
- return cpu;
-}
-
-/**
- * mcd_first_attached_cpu() - Returns the first CPU with an attached process.
- */
-static CPUState *mcd_first_attached_cpu(void)
-{
- CPUState *cpu = first_cpu;
- MCDProcess *process = mcd_get_cpu_process(cpu);
-
- if (!process->attached) {
- return mcd_next_attached_cpu(cpu);
- }
-
- return cpu;
-}
-
/**
* mcd_chr_event() - Handles a TCP client connect.
*
--
2.34.1
next prev parent reply other threads:[~2023-12-20 16:29 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 16:25 [PATCH v5 00/18] first version of mcdstub Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 01/18] gdbstub, mcdstub: file and build structure adapted to accomodate for the mcdstub Nicolas Eder
2024-02-29 15:33 ` Alex Bennée
2023-12-20 16:25 ` [PATCH v5 02/18] gdbstub: hex conversion functions moved to cutils.h Nicolas Eder
2024-02-29 15:33 ` Alex Bennée
2023-12-20 16:25 ` [PATCH v5 03/18] gdbstub: GDBRegisterState moved to gdbstub.h so it can be used outside of the gdbstub Nicolas Eder
2024-02-29 15:23 ` Alex Bennée
2023-12-20 16:25 ` [PATCH v5 04/18] gdbstub: DebugClass added to system mode Nicolas Eder
2024-02-29 16:35 ` Alex Bennée
2024-03-05 11:27 ` nicolas.eder
2023-12-20 16:25 ` [PATCH v5 05/18] mcdstub: memory helper functions added Nicolas Eder
2024-02-29 16:56 ` Alex Bennée
2024-03-05 11:03 ` nicolas.eder
2023-12-20 16:25 ` [PATCH v5 06/18] mcdstub: -mcd start option added, mcd specific defines added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 07/18] mcdstub: mcdserver initialization functions added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 08/18] cutils: qemu_strtou32 function added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 09/18] mcdstub: TCP packet plumbing added Nicolas Eder
2023-12-20 16:25 ` Nicolas Eder [this message]
2023-12-20 16:25 ` [PATCH v5 11/18] mcdstub: system and core queries added Nicolas Eder
2024-02-29 15:11 ` Alex Bennée
2024-03-05 11:08 ` nicolas.eder
2023-12-20 16:25 ` [PATCH v5 12/18] mcdstub: all core specific " Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 13/18] mcdstub: go, step and break added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 14/18] mcdstub: state query added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 15/18] mcdstub: skeleton for reset handling added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 16/18] mcdstub: register access added Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 17/18] mcdstub: memory " Nicolas Eder
2023-12-20 16:25 ` [PATCH v5 18/18] mcdstub: break/watchpoints added Nicolas Eder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231220162555.19545-11-nicolas.eder@lauterbach.com \
--to=nicolas.eder@lauterbach.com \
--cc=alex.bennee@linaro.org \
--cc=christian.boenig@lauterbach.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).