OpenOCD
target/rtt.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 #include <helper/log.h>
14 #include <helper/binarybuffer.h>
15 #include <helper/command.h>
16 #include <rtt/rtt.h>
17 #include <target/rtt.h>
18 
19 #include "target.h"
20 
21 // Offsets for RTT control block parameters.
23  unsigned int channel_size;
24  unsigned int buffer_addr_offset;
25  unsigned int size_offset;
26  unsigned int write_pos_offset;
27  unsigned int read_pos_offset;
28  unsigned int flags_offset;
29 };
30 
31 // Offsets for 32-bit architecture.
32 static const struct rtt_control_params rtt_params_32 = {
34  .buffer_addr_offset = 4,
35  .size_offset = 8,
36  .write_pos_offset = 12,
37  .read_pos_offset = 16,
38  .flags_offset = 20
39 };
40 
41 // Offsets for 64-bit architecture.
42 static const struct rtt_control_params rtt_params_64 = {
44  .buffer_addr_offset = 8,
45  .size_offset = 16,
46  .write_pos_offset = 20,
47  .read_pos_offset = 24,
48  .flags_offset = 28
49 };
50 
51 static const struct rtt_control_params *get_rtt_params(struct target *target)
52 {
53  if (target_address_bits(target) == 64)
54  return &rtt_params_64;
55  return &rtt_params_32;
56 }
57 
58 static int read_rtt_channel(struct target *target,
59  const struct rtt_control *ctrl, unsigned int channel_index,
60  enum rtt_channel_type type, struct rtt_channel *channel)
61 {
62  int ret;
63  uint8_t buf[RTT_CHANNEL_SIZE_64];
65  const struct rtt_control_params *params = get_rtt_params(target);
66 
67  address = ctrl->address + RTT_CB_SIZE + (channel_index * params->channel_size);
68 
71 
72  ret = target_read_buffer(target, address, params->channel_size, buf);
73 
74  if (ret != ERROR_OK)
75  return ret;
76 
77  channel->address = address;
78  if (target_address_bits(target) == 64) {
79  channel->name_addr = target_buffer_get_u64(target, buf + 0);
81  } else {
82  channel->name_addr = target_buffer_get_u32(target, buf + 0);
84  }
85  channel->size = target_buffer_get_u32(target, buf + params->size_offset);
86  channel->write_pos = target_buffer_get_u32(target, buf + params->write_pos_offset);
87  channel->read_pos = target_buffer_get_u32(target, buf + params->read_pos_offset);
88  channel->flags = target_buffer_get_u32(target, buf + params->flags_offset);
89  return ERROR_OK;
90 }
91 
92 int target_rtt_start(struct target *target, const struct rtt_control *ctrl,
93  void *user_data)
94 {
95  return ERROR_OK;
96 }
97 
98 int target_rtt_stop(struct target *target, void *user_data)
99 {
100  return ERROR_OK;
101 }
102 
104  char *name, size_t length)
105 {
106  size_t offset;
107 
108  offset = 0;
109 
110  while (offset < length) {
111  int ret;
112  size_t read_length;
113 
114  read_length = MIN(32, length - offset);
115  ret = target_read_buffer(target, address + offset, read_length,
116  (uint8_t *)name + offset);
117 
118  if (ret != ERROR_OK)
119  return ret;
120 
121  if (memchr(name + offset, '\0', read_length))
122  return ERROR_OK;
123 
124  offset += read_length;
125  }
126 
127  name[length - 1] = '\0';
128 
129  return ERROR_OK;
130 }
131 
132 static int write_to_channel(struct target *target,
133  const struct rtt_channel *channel, const uint8_t *buffer,
134  size_t *length)
135 {
136  int ret;
137  uint32_t len;
138 
139  if (!*length)
140  return ERROR_OK;
141 
142  if (channel->write_pos == channel->read_pos) {
143  uint32_t first_length;
144 
145  len = MIN(*length, channel->size - 1);
146  first_length = MIN(len, channel->size - channel->write_pos);
147 
149  channel->buffer_addr + channel->write_pos, first_length,
150  buffer);
151 
152  if (ret != ERROR_OK)
153  return ret;
154 
155  ret = target_write_buffer(target, channel->buffer_addr,
156  len - first_length, buffer + first_length);
157 
158  if (ret != ERROR_OK)
159  return ret;
160  } else if (channel->write_pos < channel->read_pos) {
161  len = MIN(*length, channel->read_pos - channel->write_pos - 1);
162 
163  if (!len) {
164  *length = 0;
165  return ERROR_OK;
166  }
167 
169  channel->buffer_addr + channel->write_pos, len, buffer);
170 
171  if (ret != ERROR_OK)
172  return ret;
173  } else {
174  uint32_t first_length;
175 
176  len = MIN(*length,
177  channel->size - channel->write_pos + channel->read_pos - 1);
178 
179  if (!len) {
180  *length = 0;
181  return ERROR_OK;
182  }
183 
184  first_length = MIN(len, channel->size - channel->write_pos);
185 
187  channel->buffer_addr + channel->write_pos, first_length,
188  buffer);
189 
190  if (ret != ERROR_OK)
191  return ret;
192 
193  buffer = buffer + first_length;
194 
195  ret = target_write_buffer(target, channel->buffer_addr,
196  len - first_length, buffer);
197 
198  if (ret != ERROR_OK)
199  return ret;
200  }
201 
202  const struct rtt_control_params *params = get_rtt_params(target);
203  ret = target_write_u32(target, channel->address + params->write_pos_offset,
204  (channel->write_pos + len) % channel->size);
205 
206  if (ret != ERROR_OK)
207  return ret;
208 
209  *length = len;
210 
211  return ERROR_OK;
212 }
213 
214 static bool channel_is_active(const struct rtt_channel *channel)
215 {
216  if (!channel)
217  return false;
218 
219  if (!channel->size)
220  return false;
221 
222  return true;
223 }
224 
226  unsigned int channel_index, const uint8_t *buffer, size_t *length,
227  void *user_data)
228 {
229  int ret;
230  struct rtt_channel channel;
231 
232  ret = read_rtt_channel(target, ctrl, channel_index,
233  RTT_CHANNEL_TYPE_DOWN, &channel);
234 
235  if (ret != ERROR_OK) {
236  LOG_ERROR("rtt: Failed to read down-channel %u description",
237  channel_index);
238  return ret;
239  }
240 
241  if (!channel_is_active(&channel)) {
242  LOG_WARNING("rtt: Down-channel %u is not active", channel_index);
243  return ERROR_OK;
244  }
245 
246  if (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {
247  LOG_WARNING("rtt: Down-channel %u is not large enough",
248  channel_index);
249  return ERROR_OK;
250  }
251 
252  ret = write_to_channel(target, &channel, buffer, length);
253 
254  if (ret != ERROR_OK)
255  return ret;
256 
257  LOG_DEBUG("rtt: Wrote %zu bytes into down-channel %u", *length,
258  channel_index);
259 
260  return ERROR_OK;
261 }
262 
264  target_addr_t address, struct rtt_control *ctrl, void *user_data)
265 {
266  int ret;
267  uint8_t buf[RTT_CB_SIZE];
268 
270 
271  if (ret != ERROR_OK)
272  return ret;
273 
274  memcpy(ctrl->id, buf, RTT_CB_MAX_ID_LENGTH);
275  ctrl->id[RTT_CB_MAX_ID_LENGTH - 1] = '\0';
278 
279  return ERROR_OK;
280 }
281 
283  target_addr_t *address, size_t size, const char *id, bool *found,
284  void *user_data)
285 {
286  target_addr_t address_end = *address + size;
287  uint8_t buf[1024];
288 
289  *found = false;
290 
291  size_t id_matched_length = 0;
292  const size_t id_length = strlen(id);
293 
294  LOG_INFO("rtt: Searching for control block '%s'", id);
295 
296  for (target_addr_t addr = *address; addr < address_end; addr += sizeof(buf)) {
297  int ret;
298 
299  const size_t buf_size = MIN(sizeof(buf), address_end - addr);
300  ret = target_read_buffer(target, addr, buf_size, buf);
301 
302  if (ret != ERROR_OK)
303  return ret;
304 
305  for (size_t buf_off = 0; buf_off < buf_size; buf_off++) {
306  if (id_matched_length > 0 &&
307  buf[buf_off] != id[id_matched_length]) {
308  /* Start from beginning */
309  id_matched_length = 0;
310  }
311 
312  if (buf[buf_off] == id[id_matched_length])
313  id_matched_length++;
314 
315  if (id_matched_length == id_length) {
316  *address = addr + buf_off + 1 - id_length;
317  *found = true;
318  return ERROR_OK;
319  }
320  }
321  }
322 
323  return ERROR_OK;
324 }
325 
327  const struct rtt_control *ctrl, unsigned int channel_index,
329  void *user_data)
330 {
331  int ret;
332  struct rtt_channel channel;
333 
334  ret = read_rtt_channel(target, ctrl, channel_index, type, &channel);
335 
336  if (ret != ERROR_OK) {
337  LOG_ERROR("rtt: Failed to read channel %u description",
338  channel_index);
339  return ret;
340  }
341 
342  info->size = channel.size;
343  info->flags = channel.flags;
344 
345  if (!channel_is_active(&channel))
346  return ERROR_OK;
347 
348  ret = read_channel_name(target, channel.name_addr, info->name,
349  info->name_length);
350 
351  if (ret != ERROR_OK)
352  return ret;
353 
354  return ERROR_OK;
355 }
356 
357 static int read_from_channel(struct target *target,
358  const struct rtt_channel *channel, uint8_t *buffer,
359  size_t *length)
360 {
361  int ret;
362  uint32_t len;
363 
364  if (!*length)
365  return ERROR_OK;
366 
367  if (channel->read_pos == channel->write_pos) {
368  len = 0;
369  } else if (channel->read_pos < channel->write_pos) {
370  len = MIN(*length, channel->write_pos - channel->read_pos);
371 
373  channel->buffer_addr + channel->read_pos, len, buffer);
374 
375  if (ret != ERROR_OK)
376  return ret;
377  } else {
378  uint32_t first_length;
379 
380  len = MIN(*length,
381  channel->size - channel->read_pos + channel->write_pos);
382  first_length = MIN(len, channel->size - channel->read_pos);
383 
385  channel->buffer_addr + channel->read_pos, first_length, buffer);
386 
387  if (ret != ERROR_OK)
388  return ret;
389 
390  ret = target_read_buffer(target, channel->buffer_addr,
391  len - first_length, buffer + first_length);
392 
393  if (ret != ERROR_OK)
394  return ret;
395  }
396 
397  if (len > 0) {
398  const struct rtt_control_params *params = get_rtt_params(target);
399  ret = target_write_u32(target, channel->address + params->read_pos_offset,
400  (channel->read_pos + len) % channel->size);
401 
402  if (ret != ERROR_OK)
403  return ret;
404  }
405 
406  *length = len;
407 
408  return ERROR_OK;
409 }
410 
412  const struct rtt_control *ctrl, struct rtt_sink_list **sinks,
413  size_t num_channels, void *user_data)
414 {
415  num_channels = MIN(num_channels, ctrl->num_up_channels);
416 
417  for (size_t i = 0; i < num_channels; i++) {
418  int ret;
419  struct rtt_channel channel;
420  uint8_t buffer[1024];
421  size_t length;
422 
423  if (!sinks[i])
424  continue;
425 
427  &channel);
428 
429  if (ret != ERROR_OK) {
430  LOG_ERROR("rtt: Failed to read up-channel %zu description", i);
431  return ret;
432  }
433 
434  if (!channel_is_active(&channel)) {
435  LOG_WARNING("rtt: Up-channel %zu is not active", i);
436  continue;
437  }
438 
439  if (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {
440  LOG_WARNING("rtt: Up-channel %zu is not large enough", i);
441  continue;
442  }
443 
444  length = sizeof(buffer);
445  ret = read_from_channel(target, &channel, buffer, &length);
446 
447  if (ret != ERROR_OK) {
448  LOG_ERROR("rtt: Failed to read from up-channel %zu", i);
449  return ret;
450  }
451 
452  for (struct rtt_sink_list *sink = sinks[i]; sink; sink = sink->next)
453  sink->read(i, buffer, length, sink->user_data);
454  }
455 
456  return ERROR_OK;
457 }
const char * name
Definition: armv4_5.c:76
Support functions to access arbitrary bits in a byte array.
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t address
Starting address. Sector aligned.
Definition: dw-spi-helper.h:0
uint8_t type
Definition: esp_usb_jtag.c:0
uint8_t length
Definition: esp_usb_jtag.c:1
#define LOG_WARNING(expr ...)
Definition: log.h:144
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
#define MIN(a, b)
Definition: replacements.h:22
target_addr_t addr
Start address to search for the control block.
Definition: rtt/rtt.c:28
struct rtt_control ctrl
Control block.
Definition: rtt/rtt.c:25
#define RTT_CHANNEL_SIZE_64
Definition: rtt/rtt.h:28
#define RTT_CB_SIZE
Definition: rtt/rtt.h:22
#define RTT_CB_MAX_ID_LENGTH
Control block ID length in bytes, including the trailing null-terminator.
Definition: rtt/rtt.h:19
#define RTT_CHANNEL_BUFFER_MIN_SIZE
Definition: rtt/rtt.h:31
#define RTT_CHANNEL_SIZE_32
Definition: rtt/rtt.h:25
rtt_channel_type
Channel type.
Definition: rtt/rtt.h:94
@ RTT_CHANNEL_TYPE_UP
Up channel (target to host).
Definition: rtt/rtt.h:96
@ RTT_CHANNEL_TYPE_DOWN
Down channel (host to target).
Definition: rtt/rtt.h:98
RTT channel information.
Definition: rtt/rtt.h:68
RTT channel.
Definition: rtt/rtt.h:46
uint32_t read_pos
Read position within the buffer in bytes.
Definition: rtt/rtt.h:58
target_addr_t buffer_addr
Buffer address on the target.
Definition: rtt/rtt.h:52
target_addr_t address
Channel structure address on the target.
Definition: rtt/rtt.h:48
uint32_t write_pos
Write position within the buffer in bytes.
Definition: rtt/rtt.h:56
uint32_t size
Channel buffer size in bytes.
Definition: rtt/rtt.h:54
target_addr_t name_addr
Channel name address on the target.
Definition: rtt/rtt.h:50
uint32_t flags
Buffer flags.
Definition: rtt/rtt.h:64
unsigned int channel_size
Definition: target/rtt.c:23
unsigned int read_pos_offset
Definition: target/rtt.c:27
unsigned int write_pos_offset
Definition: target/rtt.c:26
unsigned int flags_offset
Definition: target/rtt.c:28
unsigned int buffer_addr_offset
Definition: target/rtt.c:24
unsigned int size_offset
Definition: target/rtt.c:25
RTT control block.
Definition: rtt/rtt.h:34
char id[RTT_CB_MAX_ID_LENGTH]
Control block identifier, including trailing null-terminator.
Definition: rtt/rtt.h:38
target_addr_t address
Control block address on the target.
Definition: rtt/rtt.h:36
uint32_t num_up_channels
Maximum number of up-channels.
Definition: rtt/rtt.h:40
uint32_t num_down_channels
Maximum number of down-channels.
Definition: rtt/rtt.h:42
struct rtt_sink_list * next
Definition: rtt/rtt.h:90
Definition: target.h:119
int target_rtt_read_control_block(struct target *target, target_addr_t address, struct rtt_control *ctrl, void *user_data)
Definition: target/rtt.c:263
static int read_from_channel(struct target *target, const struct rtt_channel *channel, uint8_t *buffer, size_t *length)
Definition: target/rtt.c:357
static int read_channel_name(struct target *target, target_addr_t address, char *name, size_t length)
Definition: target/rtt.c:103
static int read_rtt_channel(struct target *target, const struct rtt_control *ctrl, unsigned int channel_index, enum rtt_channel_type type, struct rtt_channel *channel)
Definition: target/rtt.c:58
static bool channel_is_active(const struct rtt_channel *channel)
Definition: target/rtt.c:214
int target_rtt_read_callback(struct target *target, const struct rtt_control *ctrl, struct rtt_sink_list **sinks, size_t num_channels, void *user_data)
Definition: target/rtt.c:411
static int write_to_channel(struct target *target, const struct rtt_channel *channel, const uint8_t *buffer, size_t *length)
Definition: target/rtt.c:132
static const struct rtt_control_params * get_rtt_params(struct target *target)
Definition: target/rtt.c:51
int target_rtt_find_control_block(struct target *target, target_addr_t *address, size_t size, const char *id, bool *found, void *user_data)
Definition: target/rtt.c:282
int target_rtt_stop(struct target *target, void *user_data)
Definition: target/rtt.c:98
int target_rtt_start(struct target *target, const struct rtt_control *ctrl, void *user_data)
Definition: target/rtt.c:92
static const struct rtt_control_params rtt_params_32
Definition: target/rtt.c:32
int target_rtt_write_callback(struct target *target, struct rtt_control *ctrl, unsigned int channel_index, const uint8_t *buffer, size_t *length, void *user_data)
Definition: target/rtt.c:225
static const struct rtt_control_params rtt_params_64
Definition: target/rtt.c:42
int target_rtt_read_channel_info(struct target *target, const struct rtt_control *ctrl, unsigned int channel_index, enum rtt_channel_type type, struct rtt_channel_info *info, void *user_data)
Definition: target/rtt.c:326
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
Definition: target.c:317
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2369
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2434
unsigned int target_address_bits(struct target *target)
Return the number of address bits this target supports.
Definition: target.c:1482
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2635
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:326
uint64_t target_addr_t
Definition: types.h:279
static struct ublast_lowlevel_priv info
uint8_t offset[4]
Definition: vdebug.c:9