OpenOCD
smp.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * *
5  * Copyright (C) ST-Ericsson SA 2011 *
6  * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson. *
7  ***************************************************************************/
8 
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12 
13 #include "server/server.h"
14 
15 #include "target/target.h"
16 
17 #include "server/gdb_server.h"
18 #include "smp.h"
19 #include "helper/binarybuffer.h"
20 
21 /* DEPRECATED: gdb_read_smp_packet/gdb_write_smp_packet to be removed */
22 /* implementation of new packet in gdb interface for smp feature */
23 /* */
24 /* j : smp status request */
25 /* J : smp set request */
26 /* */
27 /* jc :read core id displayed by gdb connection */
28 /* reply XXXXXXXX core id is int32_t , 8 hex digits */
29 /* */
30 /* Reply ENN error not supported (target not smp) */
31 /* */
32 /* JcXX set core id displayed at next gdb continue */
33 /* maximum 8 bytes described core id int32_t (8 hex digits) */
34 /* (core id -1 , reserved for returning to normal continue mode) */
35 /* Reply ENN error not supported(target not smp,core id out of range) */
36 /* Reply OK : for success */
37 /* */
38 /* handling of this packet within gdb can be done by the creation */
39 /* internal variable by mean of function allocate_computed_value */
40 /* set $_core 1 => Jc01 packet is sent */
41 /* print $_core => jc packet is sent and result is affected in $ */
42 /* Another way to test this packet is the usage of maintenance packet */
43 /* maint packet Jc01 */
44 /* maint packet jc */
45 
46 /* packet j :smp status request */
47 #define DEPRECATED_MSG "DEPRECATED: This method is deprecated in favor of the hwthread pseudo RTOS"
49  char const *packet, int packet_size)
50 {
52  int retval = ERROR_OK;
53 
55 
56  if (target->smp) {
57  if (strncmp(packet, "jc", 2) == 0) {
58  const uint32_t len = sizeof(target->gdb_service->core[0]);
59  char hex_buffer[len * 2 + 1];
60  uint8_t buffer[len];
61  buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
62  size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),
63  sizeof(hex_buffer));
64 
65  retval = gdb_put_packet(connection, hex_buffer, pkt_len);
66  }
67  } else
68  retval = gdb_put_packet(connection, "E01", 3);
69  return retval;
70 }
71 
72 /* J : smp set request */
74  char const *packet, int packet_size)
75 {
77  char *separator;
78  int coreid = 0;
79  int retval = ERROR_OK;
80 
82 
83  /* skip command character */
84  if (target->smp) {
85  if (strncmp(packet, "Jc", 2) == 0) {
86  packet += 2;
87  coreid = strtoul(packet, &separator, 16);
89  retval = gdb_put_packet(connection, "OK", 2);
90  }
91  } else
92  retval = gdb_put_packet(connection, "E01", 3);
93 
94  return retval;
95 }
96 
97 COMMAND_HANDLER(default_handle_smp_command)
98 {
100  struct target_list *head;
101 
102  if (CMD_ARGC > 1)
104 
105  if (!CMD_ARGC) {
106  command_print(CMD, "%s", target->smp ? "on" : "off");
107  return ERROR_OK;
108  }
109 
110  if (!strcmp(CMD_ARGV[0], "on")) {
112  head->target->smp = 1;
113 
114  return ERROR_OK;
115  }
116 
117  if (!strcmp(CMD_ARGV[0], "off")) {
119  head->target->smp = 0;
120 
121  /* fixes the target display to the debugger */
124 
125  return ERROR_OK;
126  }
127 
129 }
130 
131 COMMAND_HANDLER(handle_smp_gdb_command)
132 {
134  int retval = ERROR_OK;
135  if (!list_empty(target->smp_targets)) {
136  if (CMD_ARGC == 1) {
137  int coreid = 0;
139  if (retval != ERROR_OK)
140  return retval;
141  target->gdb_service->core[1] = coreid;
142 
143  }
144  command_print(CMD, "gdb coreid %" PRId32 " -> %" PRId32, target->gdb_service->core[0]
145  , target->gdb_service->core[1]);
146  }
147  return ERROR_OK;
148 }
149 
151  {
152  .name = "smp",
153  .handler = default_handle_smp_command,
154  .mode = COMMAND_EXEC,
155  .help = "smp handling",
156  .usage = "[on|off]",
157  },
158  {
159  .name = "smp_gdb",
160  .handler = handle_smp_gdb_command,
161  .mode = COMMAND_EXEC,
162  .help = "display/fix current core played to gdb",
163  .usage = "",
164  },
166 };
size_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)
Convert binary data into a string of hexadecimal pairs.
Definition: binarybuffer.c:392
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:30
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:140
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
Definition: command.h:425
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:145
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_EXEC
Definition: command.h:40
int gdb_put_packet(struct connection *connection, char *buffer, int len)
Definition: gdb_server.c:531
static struct target * get_target_from_connection(struct connection *connection)
Definition: gdb_server.h:32
static int list_empty(const struct list_head *head)
list_empty - tests whether a list is empty
Definition: list.h:296
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define ERROR_OK
Definition: log.h:155
struct target * target
Definition: rtt/rtt.c:26
int gdb_read_smp_packet(struct connection *connection, char const *packet, int packet_size)
Definition: smp.c:48
COMMAND_HANDLER(default_handle_smp_command)
Definition: smp.c:97
int gdb_write_smp_packet(struct connection *connection, char const *packet, int packet_size)
Definition: smp.c:73
#define DEPRECATED_MSG
Definition: smp.c:47
const struct command_registration smp_command_handlers[]
Definition: smp.c:150
#define foreach_smp_target(pos, head)
Definition: smp.h:15
const char * name
Definition: command.h:229
int32_t core[2]
Definition: target.h:104
struct target * target
Definition: target.h:99
struct target * target
Definition: target.h:215
Definition: target.h:120
int32_t coreid
Definition: target.h:125
int smp
Definition: target.h:192
struct gdb_service * gdb_service
Definition: target.h:200
struct list_head * smp_targets
Definition: target.h:193
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:536