You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

413 lines
9.2 KiB

  1. /*
  2. * Copyright (C) 2016-2017 by Marc Schink
  3. * openocd-dev@marcschink.de
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <stddef.h>
  19. #include <stdint.h>
  20. #include <helper/log.h>
  21. #include <helper/binarybuffer.h>
  22. #include <helper/command.h>
  23. #include <rtt/rtt.h>
  24. #include "target.h"
  25. static uint8_t rtt_buffer[1024];
  26. static int read_rtt_buffer(struct target *target,
  27. const struct rtt_control *ctrl, unsigned int channel,
  28. enum rtt_channel_type type, struct rtt_buffer *buffer)
  29. {
  30. int ret;
  31. uint8_t buf[RTT_BUFFER_LENGTH];
  32. target_addr_t address;
  33. address = ctrl->address + RTT_CB_LENGTH + (channel * RTT_BUFFER_LENGTH);
  34. if (type == RTT_CHANNEL_TYPE_DOWN)
  35. address += ctrl->num_up_buffers * RTT_BUFFER_LENGTH;
  36. ret = target_read_buffer(target, address, RTT_BUFFER_LENGTH, buf);
  37. if (ret != ERROR_OK)
  38. return ret;
  39. buffer->address = address;
  40. buffer->name_addr = buf_get_u32(buf, 0, 32);
  41. buffer->buffer_addr = buf_get_u32(buf + 4, 0, 32);
  42. buffer->size = buf_get_u32(buf + 8, 0, 32);
  43. buffer->write_offset = buf_get_u32(buf + 12, 0, 32);
  44. buffer->read_offset = buf_get_u32(buf + 16, 0, 32);
  45. buffer->flags = buf_get_u32(buf + 20, 0, 32);
  46. return ERROR_OK;
  47. }
  48. int target_rtt_start(const struct rtt_control *ctrl, struct target *target,
  49. void *user_data)
  50. {
  51. return ERROR_OK;
  52. }
  53. int target_rtt_stop(struct target *target, void *user_data)
  54. {
  55. return ERROR_OK;
  56. }
  57. static int read_buffer_name(struct target *target, target_addr_t address,
  58. char *name, size_t length)
  59. {
  60. size_t offset;
  61. offset = 0;
  62. while (offset < length) {
  63. int ret;
  64. size_t tmp;
  65. tmp = MIN(32, length - offset);
  66. ret = target_read_buffer(target, address + offset, tmp,
  67. (uint8_t *)name + offset);
  68. if (ret != ERROR_OK)
  69. return ret;
  70. if (memchr(name + offset, '\0', tmp))
  71. return ERROR_OK;
  72. offset += tmp;
  73. }
  74. name[length - 1] = '\0';
  75. return ERROR_OK;
  76. }
  77. static int write_to_channel(struct target *target,
  78. const struct rtt_buffer *rttbuf, const uint8_t *buffer, size_t *length)
  79. {
  80. int ret;
  81. uint32_t len;
  82. if (!*length)
  83. return ERROR_OK;
  84. if (rttbuf->write_offset == rttbuf->read_offset) {
  85. uint32_t first_length;
  86. len = MIN(*length, rttbuf->size - 1);
  87. first_length = MIN(len, rttbuf->size - rttbuf->write_offset);
  88. ret = target_write_buffer(target,
  89. rttbuf->buffer_addr + rttbuf->write_offset, first_length, buffer);
  90. if (ret != ERROR_OK)
  91. return ret;
  92. ret = target_write_buffer(target, rttbuf->buffer_addr,
  93. len - first_length, buffer + first_length);
  94. if (ret != ERROR_OK)
  95. return ret;
  96. } else if (rttbuf->write_offset < rttbuf->read_offset) {
  97. len = MIN(*length, rttbuf->read_offset - rttbuf->write_offset - 1);
  98. if (!len) {
  99. *length = 0;
  100. return ERROR_OK;
  101. }
  102. ret = target_write_buffer(target,
  103. rttbuf->buffer_addr + rttbuf->write_offset, len, buffer);
  104. if (ret != ERROR_OK)
  105. return ret;
  106. } else {
  107. uint32_t first_length;
  108. len = MIN(*length,
  109. rttbuf->size - rttbuf->write_offset + rttbuf->read_offset - 1);
  110. if (!len) {
  111. *length = 0;
  112. return ERROR_OK;
  113. }
  114. first_length = MIN(len, rttbuf->size - rttbuf->write_offset);
  115. ret = target_write_buffer(target,
  116. rttbuf->buffer_addr + rttbuf->write_offset, first_length, buffer);
  117. if (ret != ERROR_OK)
  118. return ret;
  119. buffer = buffer + first_length;
  120. ret = target_write_buffer(target, rttbuf->buffer_addr,
  121. len - first_length, buffer);
  122. if (ret != ERROR_OK)
  123. return ret;
  124. }
  125. ret = target_write_u32(target, rttbuf->address + 12,
  126. (rttbuf->write_offset + len) % rttbuf->size);
  127. if (ret != ERROR_OK)
  128. return ret;
  129. *length = len;
  130. return ERROR_OK;
  131. }
  132. static bool buffer_is_active(const struct rtt_buffer *buf)
  133. {
  134. if (!buf)
  135. return false;
  136. if (!buf->size)
  137. return false;
  138. return true;
  139. }
  140. int target_rtt_write_callback(struct rtt_control *ctrl,
  141. unsigned int channel, const uint8_t *buffer, size_t *length,
  142. struct target *target, void *user_data)
  143. {
  144. int ret;
  145. struct rtt_buffer rttbuf;
  146. ret = read_rtt_buffer(target, ctrl, channel, RTT_CHANNEL_TYPE_DOWN, &rttbuf);
  147. if (ret != ERROR_OK) {
  148. LOG_ERROR("Failed to read RTT buffer of down-channel %u", channel);
  149. return ret;
  150. }
  151. if (!buffer_is_active(&rttbuf)) {
  152. LOG_WARNING("Down-channel %u is not active", channel);
  153. return ERROR_OK;
  154. }
  155. if (rttbuf.size < RTT_MIN_BUFFER_SIZE) {
  156. LOG_WARNING("Down-channel %u is not large enough", channel);
  157. return ERROR_OK;
  158. }
  159. ret = write_to_channel(target, &rttbuf, buffer, length);
  160. if (ret != ERROR_OK)
  161. return ret;
  162. LOG_DEBUG("Wrote %zu bytes into RTT down-channel %u", *length, channel);
  163. return ERROR_OK;
  164. }
  165. int target_rtt_read_control_block(target_addr_t address,
  166. struct rtt_control *ctrl, struct target *target, void *user_data)
  167. {
  168. int ret;
  169. uint8_t buf[RTT_CB_LENGTH];
  170. ret = target_read_buffer(target, address, RTT_CB_LENGTH, buf);
  171. if (ret != ERROR_OK)
  172. return ret;
  173. memcpy(ctrl->id, buf, RTT_MAX_CB_ID_LENGTH);
  174. ctrl->id[RTT_MAX_CB_ID_LENGTH] = '\0';
  175. ctrl->num_up_buffers = buf_get_u32(buf + RTT_MAX_CB_ID_LENGTH, 0, 32);
  176. ctrl->num_down_buffers = buf_get_u32(buf + RTT_MAX_CB_ID_LENGTH + 4, 0,
  177. 32);
  178. return ERROR_OK;
  179. }
  180. int target_rtt_find_control_block(target_addr_t *address, size_t length,
  181. const char *id, size_t id_length, bool *found, struct target *target,
  182. void *user_data)
  183. {
  184. target_addr_t addr;
  185. uint8_t buf[1024];
  186. size_t j;
  187. size_t start;
  188. *found = false;
  189. j = 0;
  190. start = 0;
  191. LOG_INFO("Searching for RTT control block '%s'", id);
  192. for (addr = 0; addr < length; addr = addr + sizeof(buf)) {
  193. int ret;
  194. size_t i;
  195. ret = target_read_buffer(target, *address + addr, sizeof(buf), buf);
  196. if (ret != ERROR_OK)
  197. return ret;
  198. for (i = 0; i < sizeof(buf); i++) {
  199. if (buf[i] == id[j]) {
  200. j++;
  201. } else {
  202. j = 0;
  203. start = addr + i + 1;
  204. }
  205. if (j == id_length) {
  206. *address = *address + start;
  207. *found = true;
  208. return ERROR_OK;
  209. }
  210. }
  211. }
  212. return ERROR_OK;
  213. }
  214. int target_rtt_read_buffer_info(const struct rtt_control *ctrl,
  215. unsigned int channel, enum rtt_channel_type type,
  216. struct rtt_buffer_info *info, struct target *target, void *user_data)
  217. {
  218. int ret;
  219. struct rtt_buffer rttbuf;
  220. ret = read_rtt_buffer(target, ctrl, channel, type, &rttbuf);
  221. if (ret != ERROR_OK) {
  222. LOG_ERROR("Failed to read RTT buffer of channel %u", channel);
  223. return ret;
  224. }
  225. ret = read_buffer_name(target, rttbuf.name_addr, info->name,
  226. info->name_length);
  227. if (ret != ERROR_OK)
  228. return ret;
  229. info->size = rttbuf.size;
  230. info->flags = rttbuf.flags;
  231. return ERROR_OK;
  232. }
  233. static int read_from_channel(struct target *target,
  234. const struct rtt_buffer *rttbuf, uint8_t *buffer, size_t *length)
  235. {
  236. int ret;
  237. uint32_t len;
  238. if (!*length)
  239. return ERROR_OK;
  240. if (rttbuf->read_offset == rttbuf->write_offset) {
  241. len = 0;
  242. } else if (rttbuf->read_offset < rttbuf->write_offset) {
  243. len = MIN(*length, rttbuf->write_offset - rttbuf->read_offset);
  244. ret = target_read_buffer(target,
  245. rttbuf->buffer_addr + rttbuf->read_offset, len, buffer);
  246. if (ret != ERROR_OK)
  247. return ret;
  248. } else {
  249. uint32_t first_length;
  250. len = MIN(*length,
  251. rttbuf->size - rttbuf->read_offset + rttbuf->write_offset);
  252. first_length = MIN(len, rttbuf->size - rttbuf->read_offset);
  253. ret = target_read_buffer(target,
  254. rttbuf->buffer_addr + rttbuf->read_offset, first_length, buffer);
  255. if (ret != ERROR_OK)
  256. return ret;
  257. ret = target_read_buffer(target, rttbuf->buffer_addr,
  258. len - first_length, buffer + first_length);
  259. if (ret != ERROR_OK)
  260. return ret;
  261. }
  262. if (len > 0) {
  263. ret = target_write_u32(target, rttbuf->address + 16,
  264. (rttbuf->read_offset + len) % rttbuf->size);
  265. if (ret != ERROR_OK)
  266. return ret;
  267. }
  268. *length = len;
  269. return ERROR_OK;
  270. }
  271. int target_rtt_read_callback(const struct rtt_control *ctrl,
  272. struct rtt_sink_list **sinks, size_t num_channels,
  273. struct target *target, void *user_data)
  274. {
  275. size_t channel;
  276. num_channels = MIN(num_channels, ctrl->num_up_buffers);
  277. for (channel = 0; channel < num_channels; channel++) {
  278. int ret;
  279. struct rtt_buffer rttbuf;
  280. size_t length;
  281. struct rtt_sink_list *tmp;
  282. if (!sinks[channel])
  283. continue;
  284. ret = read_rtt_buffer(target, ctrl, channel, RTT_CHANNEL_TYPE_UP,
  285. &rttbuf);
  286. if (ret != ERROR_OK) {
  287. LOG_ERROR("Failed to read RTT buffer of up-channel %zu", channel);
  288. return ret;
  289. }
  290. if (!buffer_is_active(&rttbuf)) {
  291. LOG_WARNING("Up-channel %zu is not active", channel);
  292. continue;
  293. }
  294. if (rttbuf.size < RTT_MIN_BUFFER_SIZE) {
  295. LOG_WARNING("Up-channel %zu is not large enough", channel);
  296. continue;
  297. }
  298. length = sizeof(rtt_buffer);
  299. ret = read_from_channel(target, &rttbuf, rtt_buffer, &length);
  300. if (ret != ERROR_OK) {
  301. LOG_ERROR("Failed to read from RTT up-channel %zu", channel);
  302. return ret;
  303. }
  304. for (tmp = sinks[channel]; tmp; tmp = tmp->next)
  305. tmp->read(channel, rtt_buffer, length, tmp->user_data);
  306. }
  307. return ERROR_OK;
  308. }