From: "Alex Bennée" <alex.bennee@linaro.org>
To: Nicolas Eder <nicolas.eder@lauterbach.com>
Cc: qemu-devel@nongnu.org,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
Christian.Boenig@lauterbach.com
Subject: Re: [PATCH v2 01/29] mcdstub initial commit, mcdstub file structure added
Date: Fri, 13 Oct 2023 16:51:59 +0100 [thread overview]
Message-ID: <87h6mumro1.fsf@linaro.org> (raw)
In-Reply-To: <20231006090610.26171-2-nicolas.eder@lauterbach.com>
Nicolas Eder <nicolas.eder@lauterbach.com> writes:
> From: neder <nicolas.eder@lauterbach.com>
>
> ---
> include/exec/mcdstub.h | 31 +++++++++++++
> mcdstub/mcd_softmmu.c | 85 +++++++++++++++++++++++++++++++++++
> mcdstub/mcd_syscalls.c | 0
> mcdstub/mcd_tcp_server.c | 95 ++++++++++++++++++++++++++++++++++++++++
> mcdstub/mcdstub.c | 0
> softmmu/vl.c | 4 ++
I'm afraid you got caught up in some clean-up and this file is now under
the more correctly names:
system/vl.c
> 6 files changed, 215 insertions(+)
> create mode 100644 include/exec/mcdstub.h
> create mode 100644 mcdstub/mcd_softmmu.c
> create mode 100644 mcdstub/mcd_syscalls.c
> create mode 100644 mcdstub/mcd_tcp_server.c
> create mode 100644 mcdstub/mcdstub.c
>
> diff --git a/include/exec/mcdstub.h b/include/exec/mcdstub.h
> new file mode 100644
> index 0000000000..8afbc09367
> --- /dev/null
> +++ b/include/exec/mcdstub.h
include/exec is a bit of a dumping ground. Maybe
include/mcdstub/mcdstub.h to keep it cleaner? For gdbstub we further
divide into user, system and api.h but that might be overkill.
> @@ -0,0 +1,31 @@
> +#ifndef MCDSTUB_H
> +#define MCDSTUB_H
> +
> +#define DEFAULT_MCDSTUB_PORT "1234"
> +
> +/* MCD breakpoint/watchpoint types */
> +#define MCD_BREAKPOINT_SW 0
> +#define MCD_BREAKPOINT_HW 1
> +#define MCD_WATCHPOINT_WRITE 2
> +#define MCD_WATCHPOINT_READ 3
> +#define MCD_WATCHPOINT_ACCESS 4
> +
> +
> +/* Get or set a register. Returns the size of the register. */
> +typedef int (*gdb_get_reg_cb)(CPUArchState *env, GByteArray *buf, int reg);
> +typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
> +void gdb_register_coprocessor(CPUState *cpu,
> + gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
> + int num_regs, const char *xml, int
> g_pos);
Why repeat these definitions instead just including gdbstub.h? We can
move the typedefs if you don't want to pollute the include with other
ephemera.
> +
> +/**
> + * mcdserver_start: start the mcd server
> + * @port_or_device: connection spec for mcd
> + *
> + * This is a TCP port
> + */
> +int mcdserver_start(const char *port_or_device);
> +
> +void gdb_set_stop_cpu(CPUState *cpu);
> +
> +#endif
> diff --git a/mcdstub/mcd_softmmu.c b/mcdstub/mcd_softmmu.c
> new file mode 100644
> index 0000000000..17e1d3ca1b
> --- /dev/null
> +++ b/mcdstub/mcd_softmmu.c
rename ;-)
> @@ -0,0 +1,85 @@
> +/*
> + * this handeles all system emulation functions for the mcdstub
> + */
> +
> +#include "exec/mcdstub.h"
> +
> +int mcdserver_start(const char *device)
> +{
> + trace_gdbstub_op_start(device);
> +
> + char gdbstub_device_name[128];
> + Chardev *chr = NULL;
> + Chardev *mon_chr;
> +
> + if (!first_cpu) {
> + error_report("gdbstub: meaningless to attach gdb to a "
> + "machine without any CPU.");
> + return -1;
> + }
> +
> + if (!gdb_supports_guest_debug()) {
> + error_report("gdbstub: current accelerator doesn't "
> + "support guest debugging");
> + return -1;
> + }
> +
> + if (!device) {
> + return -1;
> + }
> + if (strcmp(device, "none") != 0) {
> + if (strstart(device, "tcp:", NULL)) {
> + /* enforce required TCP attributes */
> + snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
> + "%s,wait=off,nodelay=on,server=on", device);
> + device = gdbstub_device_name;
> + }
> +#ifndef _WIN32
> + else if (strcmp(device, "stdio") == 0) {
> + struct sigaction act;
> +
> + memset(&act, 0, sizeof(act));
> + act.sa_handler = gdb_sigterm_handler;
> + sigaction(SIGINT, &act, NULL);
> + }
> +#endif
> + /*
> + * FIXME: it's a bit weird to allow using a mux chardev here
> + * and implicitly setup a monitor. We may want to break this.
> + */
> + chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
> + if (!chr) {
> + return -1;
> + }
> + }
> +
> + if (!gdbserver_state.init) {
> + gdb_init_gdbserver_state();
> +
> + qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
> +
> + /* Initialize a monitor terminal for gdb */
> + mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
> + NULL, NULL, &error_abort);
> + monitor_init_hmp(mon_chr, false, &error_abort);
> + } else {
> + qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
> + mon_chr = gdbserver_system_state.mon_chr;
> + reset_gdbserver_state();
> + }
> +
> + create_processes(&gdbserver_state);
> +
> + if (chr) {
> + qemu_chr_fe_init(&gdbserver_system_state.chr, chr, &error_abort);
> + qemu_chr_fe_set_handlers(&gdbserver_system_state.chr,
> + gdb_chr_can_receive,
> + gdb_chr_receive, gdb_chr_event,
> + NULL, &gdbserver_state, NULL, true);
> + }
> + gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
> + gdbserver_system_state.mon_chr = mon_chr;
> + gdb_syscall_reset();
So this is showing a lot of c&p of the gdbstub but if the intention is
to re-use chunks of gdbstub we should do it properly rather than
duplicating code.
> +
> + return 0;
> +}
> \ No newline at end of file
> diff --git a/mcdstub/mcd_syscalls.c b/mcdstub/mcd_syscalls.c
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/mcdstub/mcd_tcp_server.c b/mcdstub/mcd_tcp_server.c
> new file mode 100644
> index 0000000000..9a1baea2e4
> --- /dev/null
> +++ b/mcdstub/mcd_tcp_server.c
> @@ -0,0 +1,95 @@
> +#include <stdio.h>
> +#include <netdb.h>
> +#include <netinet/in.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/socket.h>
> +#include <sys/types.h>
> +#include <unistd.h> // read(), write(), close()
#include "qemu/osdep.h" will bring in most of the standard stuff:
Order include directives as follows:
.. code-block:: c
#include "qemu/osdep.h" /* Always first... */
#include <...> /* then system headers... */
#include "..." /* and finally QEMU headers. */
The "qemu/osdep.h" header contains preprocessor macros that affect the behavior
of core system headers like <stdint.h>. It must be the first include so that
core system headers included by external libraries get the preprocessor macros
that QEMU depends on.
See https://qemu.readthedocs.io/en/v8.1.0/devel/style.html
Running ./scripts/checkpatch.pl will pick a lot of this up.
> +#define MAX 80
> +#define DEFAULT_MCDSTUB_PORT "1234"
> +#define SA struct sockaddr
> +
> +// Function designed for chat between client and server.
c.f. style
> +void func(int connfd)
> +{
> + char buff[MAX];
> + int n;
> + // infinite loop for chat
> + for (;;) {
> + bzero(buff, MAX);
> +
> + // read the message from client and copy it in buffer
> + read(connfd, buff, sizeof(buff));
> + // print buffer which contains the client contents
> + printf("From client: %s\t To client : ", buff);
> + bzero(buff, MAX);
> + n = 0;
> + // copy server message in the buffer
> + while ((buff[n++] = getchar()) != '\n')
> + ;
> +
> + // and send that buffer to client
> + write(connfd, buff, sizeof(buff));
> +
> + // if msg contains "Exit" then server exit and chat ended.
> + if (strncmp("exit", buff, 4) == 0) {
> + printf("Server Exit...\n");
> + break;
> + }
> + }
> +}
> +
> +// Driver function
> +int main()
why main? Is this a helper?
> +{
> + int sockfd, connfd, len;
> + struct sockaddr_in servaddr, cli;
> +
> + // socket create and verification
> + sockfd = socket(AF_INET, SOCK_STREAM, 0);
> + if (sockfd == -1) {
> + printf("socket creation failed...\n");
> + exit(0);
> + }
> + else
> + printf("Socket successfully created..\n");
> + bzero(&servaddr, sizeof(servaddr));
> +
> + // assign IP, PORT
> + servaddr.sin_family = AF_INET;
> + servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
> + servaddr.sin_port = htons(DEFAULT_MCDSTUB_PORT);
> +
> + // Binding newly created socket to given IP and verification
> + if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
> + printf("socket bind failed...\n");
> + exit(0);
> + }
> + else
> + printf("Socket successfully binded..\n");
> +
> + // Now server is ready to listen and verification
> + if ((listen(sockfd, 5)) != 0) {
> + printf("Listen failed...\n");
> + exit(0);
> + }
> + else
> + printf("Server listening..\n");
> + len = sizeof(cli);
> +
> + // Accept the data packet from client and verification
> + connfd = accept(sockfd, (SA*)&cli, &len);
> + if (connfd < 0) {
> + printf("server accept failed...\n");
> + exit(0);
> + }
> + else
> + printf("server accept the client...\n");
> +
> + // Function for chatting between client and server
> + func(connfd);
> +
> + // After chatting close the socket
> + close(sockfd);
> +}
I think you need to make a design choice here about if MCD wants to
support *-user and system emulation or just system emulation. The
gdbstub does hand roll its own bind/accept code for *-user because it
doesn't include most of the rest of QEMU. However for system emulation
we use the chardev system which already provides and abstracts a lot of
this stuff. Then the code becomes simpler:
if (chr) {
qemu_chr_fe_init(&gdbserver_system_state.chr, chr, &error_abort);
qemu_chr_fe_set_handlers(&gdbserver_system_state.chr,
gdb_chr_can_receive,
gdb_chr_receive, gdb_chr_event,
NULL, &gdbserver_state, NULL, true);
}
and you check need to plug in the handlers.
> diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/softmmu/vl.c b/softmmu/vl.c
> index 98e071e63b..3278f204ea 100644
> --- a/softmmu/vl.c
> +++ b/softmmu/vl.c
> @@ -1258,6 +1258,7 @@ struct device_config {
> DEV_PARALLEL, /* -parallel */
> DEV_DEBUGCON, /* -debugcon */
> DEV_GDB, /* -gdb, -s */
> + DEV_MCD, /* -mcd */
> DEV_SCLP, /* s390 sclp */
> } type;
> const char *cmdline;
> @@ -3011,6 +3012,9 @@ void qemu_init(int argc, char **argv)
> case QEMU_OPTION_gdb:
> add_device_config(DEV_GDB, optarg);
> break;
> + case QEMU_OPTION_mcd:
> + add_device_config(DEV_MCD, optarg);
> + break;
This breaks the compile because presumably qemu-options.hx hasn't an
entry for this yet.
> case QEMU_OPTION_L:
> if (is_help_option(optarg)) {
> list_data_dirs = true;
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2023-10-13 16:09 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-06 9:05 [PATCH v2 00/29] first version of mcdstub Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 01/29] mcdstub initial commit, mcdstub file structure added Nicolas Eder
2023-10-13 15:51 ` Alex Bennée [this message]
2023-10-06 9:05 ` [PATCH v2 02/29] TCP chardev added, handshake with TRACE32 working Nicolas Eder
2023-10-13 16:15 ` Alex Bennée
2023-10-06 9:05 ` [PATCH v2 03/29] TCP packet handling added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 04/29] queries for resets and triggers added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 05/29] queries for memory spaces and register groups added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 06/29] query for registers added Nicolas Eder
2023-10-13 16:38 ` Alex Bennée
2023-10-06 9:05 ` [PATCH v2 07/29] query data preparation improved Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 08/29] shared header file added, used for TCP packet data Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 09/29] memory and register query data now stored per core Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 10/29] handler for resets added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 11/29] query for the VM state added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 12/29] handler for reading registers added Nicolas Eder
2023-10-13 16:40 ` Alex Bennée
2023-10-06 9:05 ` [PATCH v2 13/29] handler for reading memory added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 14/29] handler for single step added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 15/29] adapting to the qemu coding style Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 16/29] deleting the mcdd startup option Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 17/29] handler for breakpoints and watchpoints added Nicolas Eder
2023-10-06 9:05 ` [PATCH v2 18/29] making step and go handlers core-specific Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 19/29] adding trigger ID handling for TRACE32 Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 20/29] cp register read/write added Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 21/29] switching between secure and non-secure memory added Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 22/29] transitioning to unsinged integers in TCP packets and removing MCD-API-specific terms Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 23/29] moved all ARM code to the ARM mcdstub and added now commom header file Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 24/29] step and go handlers now propperly perform global operations Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 25/29] Doxygen documentation added Nicolas Eder
2023-10-13 16:34 ` Alex Bennée
2023-10-06 9:06 ` [PATCH v2 26/29] moved all mcd related header files into include/mcdstub Nicolas Eder
2023-10-13 16:45 ` Alex Bennée
2023-10-06 9:06 ` [PATCH v2 27/29] MCD stub entry added to maintainers file Nicolas Eder
2023-10-13 16:46 ` Alex Bennée
2023-10-06 9:06 ` [PATCH v2 28/29] added description to out-commented gdb function Nicolas Eder
2023-10-06 9:06 ` [PATCH v2 29/29] introducing the DebugClass. It is used to abstract the gdb/mcd set_stop_cpu function Nicolas Eder
2023-10-06 9:50 ` [PATCH v2 00/29] first version of mcdstub Philippe Mathieu-Daudé
2023-10-13 16:47 ` Alex Bennée
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=87h6mumro1.fsf@linaro.org \
--to=alex.bennee@linaro.org \
--cc=Christian.Boenig@lauterbach.com \
--cc=nicolas.eder@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.