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  const uint32_t len = sizeof(target->gdb_service->core[0]);
58  char hex_buffer[len * 2 + 1];
59  uint8_t buffer[len];
60  buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
61  size_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),
62  sizeof(hex_buffer));
63  retval = gdb_put_packet(connection, hex_buffer, pkt_len);
64  } else
65  retval = gdb_put_packet(connection, "E01", 3);
66  return retval;
67 }
68 
69 /* J : smp set request */
71  char const *packet, int packet_size)
72 {
74  char *separator;
75  int coreid = 0;
76  int retval = ERROR_OK;
77 
79 
80  /* skip command character */
81  if (target->smp) {
82  if (strncmp(packet, "Jc", 2) == 0) {
83  packet += 2;
84  coreid = strtoul(packet, &separator, 16);
86  retval = gdb_put_packet(connection, "OK", 2);
87  }
88  } else
89  retval = gdb_put_packet(connection, "E01", 3);
90 
91  return retval;
92 }
93 
94 COMMAND_HANDLER(default_handle_smp_command)
95 {
97  struct target_list *head;
98 
99  if (CMD_ARGC > 1)
101 
102  if (!CMD_ARGC) {
103  command_print(CMD, "%s", target->smp ? "on" : "off");
104  return ERROR_OK;
105  }
106 
107  if (!strcmp(CMD_ARGV[0], "on")) {
109  head->target->smp = 1;
110 
111  return ERROR_OK;
112  }
113 
114  if (!strcmp(CMD_ARGV[0], "off")) {
116  head->target->smp = 0;
117 
118  /* fixes the target display to the debugger */
121 
122  return ERROR_OK;
123  }
124 
126 }
127 
128 COMMAND_HANDLER(handle_smp_gdb_command)
129 {
131  int retval = ERROR_OK;
132 
134 
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:380
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:389
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:146
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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:445
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:151
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_EXEC
Definition: command.h:40
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
int gdb_put_packet(struct connection *connection, const char *buffer, int len)
Definition: gdb_server.c:554
static struct target * get_target_from_connection(struct connection *connection)
Definition: gdb_server.h:35
static int list_empty(const struct list_head *head)
Definition: list.h:61
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define ERROR_OK
Definition: log.h:182
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:94
int gdb_write_smp_packet(struct connection *connection, char const *packet, int packet_size)
Definition: smp.c:70
#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:239
int32_t core[2]
Definition: target.h:103
struct target * target
Definition: target.h:98
struct target * target
Definition: target.h:217
Definition: target.h:119
int32_t coreid
Definition: target.h:123
struct gdb_service * gdb_service
Definition: target.h:202
struct list_head * smp_targets
Definition: target.h:191
unsigned int smp
Definition: target.h:190
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: target.c:467