1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
13 #include <helper/log.h>
14 #include <helper/binarybuffer.h>
15 #include <helper/command.h>
20 static int read_rtt_channel(struct target
*target
,
21 const struct rtt_control
*ctrl
, unsigned int channel_index
,
22 enum rtt_channel_type type
, struct rtt_channel
*channel
)
25 uint8_t buf
[RTT_CHANNEL_SIZE
];
26 target_addr_t address
;
28 address
= ctrl
->address
+ RTT_CB_SIZE
+ (channel_index
* RTT_CHANNEL_SIZE
);
30 if (type
== RTT_CHANNEL_TYPE_DOWN
)
31 address
+= ctrl
->num_up_channels
* RTT_CHANNEL_SIZE
;
33 ret
= target_read_buffer(target
, address
, RTT_CHANNEL_SIZE
, buf
);
38 channel
->address
= address
;
39 channel
->name_addr
= buf_get_u32(buf
+ 0, 0, 32);
40 channel
->buffer_addr
= buf_get_u32(buf
+ 4, 0, 32);
41 channel
->size
= buf_get_u32(buf
+ 8, 0, 32);
42 channel
->write_pos
= buf_get_u32(buf
+ 12, 0, 32);
43 channel
->read_pos
= buf_get_u32(buf
+ 16, 0, 32);
44 channel
->flags
= buf_get_u32(buf
+ 20, 0, 32);
49 int target_rtt_start(struct target
*target
, const struct rtt_control
*ctrl
,
55 int target_rtt_stop(struct target
*target
, void *user_data
)
60 static int read_channel_name(struct target
*target
, target_addr_t address
,
61 char *name
, size_t length
)
67 while (offset
< length
) {
71 read_length
= MIN(32, length
- offset
);
72 ret
= target_read_buffer(target
, address
+ offset
, read_length
,
73 (uint8_t *)name
+ offset
);
78 if (memchr(name
+ offset
, '\0', read_length
))
81 offset
+= read_length
;
84 name
[length
- 1] = '\0';
89 static int write_to_channel(struct target
*target
,
90 const struct rtt_channel
*channel
, const uint8_t *buffer
,
99 if (channel
->write_pos
== channel
->read_pos
) {
100 uint32_t first_length
;
102 len
= MIN(*length
, channel
->size
- 1);
103 first_length
= MIN(len
, channel
->size
- channel
->write_pos
);
105 ret
= target_write_buffer(target
,
106 channel
->buffer_addr
+ channel
->write_pos
, first_length
,
112 ret
= target_write_buffer(target
, channel
->buffer_addr
,
113 len
- first_length
, buffer
+ first_length
);
117 } else if (channel
->write_pos
< channel
->read_pos
) {
118 len
= MIN(*length
, channel
->read_pos
- channel
->write_pos
- 1);
125 ret
= target_write_buffer(target
,
126 channel
->buffer_addr
+ channel
->write_pos
, len
, buffer
);
131 uint32_t first_length
;
134 channel
->size
- channel
->write_pos
+ channel
->read_pos
- 1);
141 first_length
= MIN(len
, channel
->size
- channel
->write_pos
);
143 ret
= target_write_buffer(target
,
144 channel
->buffer_addr
+ channel
->write_pos
, first_length
,
150 buffer
= buffer
+ first_length
;
152 ret
= target_write_buffer(target
, channel
->buffer_addr
,
153 len
- first_length
, buffer
);
159 ret
= target_write_u32(target
, channel
->address
+ 12,
160 (channel
->write_pos
+ len
) % channel
->size
);
170 static bool channel_is_active(const struct rtt_channel
*channel
)
181 int target_rtt_write_callback(struct target
*target
, struct rtt_control
*ctrl
,
182 unsigned int channel_index
, const uint8_t *buffer
, size_t *length
,
186 struct rtt_channel channel
;
188 ret
= read_rtt_channel(target
, ctrl
, channel_index
,
189 RTT_CHANNEL_TYPE_DOWN
, &channel
);
191 if (ret
!= ERROR_OK
) {
192 LOG_ERROR("rtt: Failed to read down-channel %u description",
197 if (!channel_is_active(&channel
)) {
198 LOG_WARNING("rtt: Down-channel %u is not active", channel_index
);
202 if (channel
.size
< RTT_CHANNEL_BUFFER_MIN_SIZE
) {
203 LOG_WARNING("rtt: Down-channel %u is not large enough",
208 ret
= write_to_channel(target
, &channel
, buffer
, length
);
213 LOG_DEBUG("rtt: Wrote %zu bytes into down-channel %u", *length
,
219 int target_rtt_read_control_block(struct target
*target
,
220 target_addr_t address
, struct rtt_control
*ctrl
, void *user_data
)
223 uint8_t buf
[RTT_CB_SIZE
];
225 ret
= target_read_buffer(target
, address
, RTT_CB_SIZE
, buf
);
230 memcpy(ctrl
->id
, buf
, RTT_CB_MAX_ID_LENGTH
);
231 ctrl
->id
[RTT_CB_MAX_ID_LENGTH
- 1] = '\0';
232 ctrl
->num_up_channels
= buf_get_u32(buf
+ RTT_CB_MAX_ID_LENGTH
+ 0,
234 ctrl
->num_down_channels
= buf_get_u32(buf
+ RTT_CB_MAX_ID_LENGTH
+ 4,
240 int target_rtt_find_control_block(struct target
*target
,
241 target_addr_t
*address
, size_t size
, const char *id
, bool *found
,
249 size_t cb_offset
= 0;
250 const size_t id_length
= strlen(id
);
252 LOG_INFO("rtt: Searching for control block '%s'", id
);
254 for (target_addr_t addr
= 0; addr
< size
; addr
= addr
+ sizeof(buf
)) {
257 const size_t buf_size
= MIN(sizeof(buf
), size
- addr
);
258 ret
= target_read_buffer(target
, *address
+ addr
, buf_size
, buf
);
266 while (i
< buf_size
) {
267 if (buf
[i
] != id
[j
]) {
279 if (j
== id_length
) {
280 *address
= *address
+ cb_offset
;
290 int target_rtt_read_channel_info(struct target
*target
,
291 const struct rtt_control
*ctrl
, unsigned int channel_index
,
292 enum rtt_channel_type type
, struct rtt_channel_info
*info
,
296 struct rtt_channel channel
;
298 ret
= read_rtt_channel(target
, ctrl
, channel_index
, type
, &channel
);
300 if (ret
!= ERROR_OK
) {
301 LOG_ERROR("rtt: Failed to read channel %u description",
306 ret
= read_channel_name(target
, channel
.name_addr
, info
->name
,
312 info
->size
= channel
.size
;
313 info
->flags
= channel
.flags
;
318 static int read_from_channel(struct target
*target
,
319 const struct rtt_channel
*channel
, uint8_t *buffer
,
328 if (channel
->read_pos
== channel
->write_pos
) {
330 } else if (channel
->read_pos
< channel
->write_pos
) {
331 len
= MIN(*length
, channel
->write_pos
- channel
->read_pos
);
333 ret
= target_read_buffer(target
,
334 channel
->buffer_addr
+ channel
->read_pos
, len
, buffer
);
339 uint32_t first_length
;
342 channel
->size
- channel
->read_pos
+ channel
->write_pos
);
343 first_length
= MIN(len
, channel
->size
- channel
->read_pos
);
345 ret
= target_read_buffer(target
,
346 channel
->buffer_addr
+ channel
->read_pos
, first_length
, buffer
);
351 ret
= target_read_buffer(target
, channel
->buffer_addr
,
352 len
- first_length
, buffer
+ first_length
);
359 ret
= target_write_u32(target
, channel
->address
+ 16,
360 (channel
->read_pos
+ len
) % channel
->size
);
371 int target_rtt_read_callback(struct target
*target
,
372 const struct rtt_control
*ctrl
, struct rtt_sink_list
**sinks
,
373 size_t num_channels
, void *user_data
)
375 num_channels
= MIN(num_channels
, ctrl
->num_up_channels
);
377 for (size_t i
= 0; i
< num_channels
; i
++) {
379 struct rtt_channel channel
;
380 uint8_t buffer
[1024];
386 ret
= read_rtt_channel(target
, ctrl
, i
, RTT_CHANNEL_TYPE_UP
,
389 if (ret
!= ERROR_OK
) {
390 LOG_ERROR("rtt: Failed to read up-channel %zu description", i
);
394 if (!channel_is_active(&channel
)) {
395 LOG_WARNING("rtt: Up-channel %zu is not active", i
);
399 if (channel
.size
< RTT_CHANNEL_BUFFER_MIN_SIZE
) {
400 LOG_WARNING("rtt: Up-channel %zu is not large enough", i
);
404 length
= sizeof(buffer
);
405 ret
= read_from_channel(target
, &channel
, buffer
, &length
);
407 if (ret
!= ERROR_OK
) {
408 LOG_ERROR("rtt: Failed to read from up-channel %zu", i
);
412 for (struct rtt_sink_list
*sink
= sinks
[i
]; sink
; sink
= sink
->next
)
413 sink
->read(i
, buffer
, length
, sink
->user_data
);
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)