2 * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <helper/log.h>
25 #include <helper/binarybuffer.h>
26 #include <helper/command.h>
31 static int read_rtt_channel(struct target *target,
32 const struct rtt_control *ctrl, unsigned int channel_index,
33 enum rtt_channel_type type, struct rtt_channel *channel)
36 uint8_t buf[RTT_CHANNEL_SIZE];
37 target_addr_t address;
39 address = ctrl->address + RTT_CB_SIZE + (channel_index * RTT_CHANNEL_SIZE);
41 if (type == RTT_CHANNEL_TYPE_DOWN)
42 address += ctrl->num_up_channels * RTT_CHANNEL_SIZE;
44 ret = target_read_buffer(target, address, RTT_CHANNEL_SIZE, buf);
49 channel->address = address;
50 channel->name_addr = buf_get_u32(buf + 0, 0, 32);
51 channel->buffer_addr = buf_get_u32(buf + 4, 0, 32);
52 channel->size = buf_get_u32(buf + 8, 0, 32);
53 channel->write_pos = buf_get_u32(buf + 12, 0, 32);
54 channel->read_pos = buf_get_u32(buf + 16, 0, 32);
55 channel->flags = buf_get_u32(buf + 20, 0, 32);
60 int target_rtt_start(struct target *target, const struct rtt_control *ctrl,
66 int target_rtt_stop(struct target *target, void *user_data)
71 static int read_channel_name(struct target *target, target_addr_t address,
72 char *name, size_t length)
78 while (offset < length) {
82 read_length = MIN(32, length - offset);
83 ret = target_read_buffer(target, address + offset, read_length,
84 (uint8_t *)name + offset);
89 if (memchr(name + offset, '\0', read_length))
92 offset += read_length;
95 name[length - 1] = '\0';
100 static int write_to_channel(struct target *target,
101 const struct rtt_channel *channel, const uint8_t *buffer,
110 if (channel->write_pos == channel->read_pos) {
111 uint32_t first_length;
113 len = MIN(*length, channel->size - 1);
114 first_length = MIN(len, channel->size - channel->write_pos);
116 ret = target_write_buffer(target,
117 channel->buffer_addr + channel->write_pos, first_length,
123 ret = target_write_buffer(target, channel->buffer_addr,
124 len - first_length, buffer + first_length);
128 } else if (channel->write_pos < channel->read_pos) {
129 len = MIN(*length, channel->read_pos - channel->write_pos - 1);
136 ret = target_write_buffer(target,
137 channel->buffer_addr + channel->write_pos, len, buffer);
142 uint32_t first_length;
145 channel->size - channel->write_pos + channel->read_pos - 1);
152 first_length = MIN(len, channel->size - channel->write_pos);
154 ret = target_write_buffer(target,
155 channel->buffer_addr + channel->write_pos, first_length,
161 buffer = buffer + first_length;
163 ret = target_write_buffer(target, channel->buffer_addr,
164 len - first_length, buffer);
170 ret = target_write_u32(target, channel->address + 12,
171 (channel->write_pos + len) % channel->size);
181 static bool channel_is_active(const struct rtt_channel *channel)
192 int target_rtt_write_callback(struct target *target, struct rtt_control *ctrl,
193 unsigned int channel_index, const uint8_t *buffer, size_t *length,
197 struct rtt_channel channel;
199 ret = read_rtt_channel(target, ctrl, channel_index,
200 RTT_CHANNEL_TYPE_DOWN, &channel);
202 if (ret != ERROR_OK) {
203 LOG_ERROR("rtt: Failed to read down-channel %u description",
208 if (!channel_is_active(&channel)) {
209 LOG_WARNING("rtt: Down-channel %u is not active", channel_index);
213 if (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {
214 LOG_WARNING("rtt: Down-channel %u is not large enough",
219 ret = write_to_channel(target, &channel, buffer, length);
224 LOG_DEBUG("rtt: Wrote %zu bytes into down-channel %u", *length,
230 int target_rtt_read_control_block(struct target *target,
231 target_addr_t address, struct rtt_control *ctrl, void *user_data)
234 uint8_t buf[RTT_CB_SIZE];
236 ret = target_read_buffer(target, address, RTT_CB_SIZE, buf);
241 memcpy(ctrl->id, buf, RTT_CB_MAX_ID_LENGTH);
242 ctrl->id[RTT_CB_MAX_ID_LENGTH - 1] = '\0';
243 ctrl->num_up_channels = buf_get_u32(buf + RTT_CB_MAX_ID_LENGTH + 0,
245 ctrl->num_down_channels = buf_get_u32(buf + RTT_CB_MAX_ID_LENGTH + 4,
251 int target_rtt_find_control_block(struct target *target,
252 target_addr_t *address, size_t size, const char *id, bool *found,
260 size_t cb_offset = 0;
261 const size_t id_length = strlen(id);
263 LOG_INFO("rtt: Searching for control block '%s'", id);
265 for (target_addr_t addr = 0; addr < size; addr = addr + sizeof(buf)) {
268 const size_t buf_size = MIN(sizeof(buf), size - addr);
269 ret = target_read_buffer(target, *address + addr, buf_size, buf);
277 while (i < buf_size) {
278 if (buf[i] != id[j]) {
290 if (j == id_length) {
291 *address = *address + cb_offset;
301 int target_rtt_read_channel_info(struct target *target,
302 const struct rtt_control *ctrl, unsigned int channel_index,
303 enum rtt_channel_type type, struct rtt_channel_info *info,
307 struct rtt_channel channel;
309 ret = read_rtt_channel(target, ctrl, channel_index, type, &channel);
311 if (ret != ERROR_OK) {
312 LOG_ERROR("rtt: Failed to read channel %u description",
317 ret = read_channel_name(target, channel.name_addr, info->name,
323 info->size = channel.size;
324 info->flags = channel.flags;
329 static int read_from_channel(struct target *target,
330 const struct rtt_channel *channel, uint8_t *buffer,
339 if (channel->read_pos == channel->write_pos) {
341 } else if (channel->read_pos < channel->write_pos) {
342 len = MIN(*length, channel->write_pos - channel->read_pos);
344 ret = target_read_buffer(target,
345 channel->buffer_addr + channel->read_pos, len, buffer);
350 uint32_t first_length;
353 channel->size - channel->read_pos + channel->write_pos);
354 first_length = MIN(len, channel->size - channel->read_pos);
356 ret = target_read_buffer(target,
357 channel->buffer_addr + channel->read_pos, first_length, buffer);
362 ret = target_read_buffer(target, channel->buffer_addr,
363 len - first_length, buffer + first_length);
370 ret = target_write_u32(target, channel->address + 16,
371 (channel->read_pos + len) % channel->size);
382 int target_rtt_read_callback(struct target *target,
383 const struct rtt_control *ctrl, struct rtt_sink_list **sinks,
384 size_t num_channels, void *user_data)
386 num_channels = MIN(num_channels, ctrl->num_up_channels);
388 for (size_t i = 0; i < num_channels; i++) {
390 struct rtt_channel channel;
391 uint8_t buffer[1024];
397 ret = read_rtt_channel(target, ctrl, i, RTT_CHANNEL_TYPE_UP,
400 if (ret != ERROR_OK) {
401 LOG_ERROR("rtt: Failed to read up-channel %zu description", i);
405 if (!channel_is_active(&channel)) {
406 LOG_WARNING("rtt: Up-channel %zu is not active", i);
410 if (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {
411 LOG_WARNING("rtt: Up-channel %zu is not large enough", i);
415 length = sizeof(buffer);
416 ret = read_from_channel(target, &channel, buffer, &length);
418 if (ret != ERROR_OK) {
419 LOG_ERROR("rtt: Failed to read from up-channel %zu", i);
423 for (struct rtt_sink_list *sink = sinks[i]; sink; sink = sink->next)
424 sink->read(i, buffer, length, sink->user_data);