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.

158 lines
4.4KB

  1. /***************************************************************************
  2. * Copyright (C) 2008 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * Copyright (C) 2008 by Spencer Oliver *
  5. * spen@spen-soft.co.uk *
  6. * Copyright (C) 2008 by Frederik Kriewtz *
  7. * frederik@kriewitz.eu *
  8. * *
  9. * This program is free software; you can redistribute it and/or modify *
  10. * it under the terms of the GNU General Public License as published by *
  11. * the Free Software Foundation; either version 2 of the License, or *
  12. * (at your option) any later version. *
  13. * *
  14. * This program is distributed in the hope that it will be useful, *
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  17. * GNU General Public License for more details. *
  18. * *
  19. * You should have received a copy of the GNU General Public License *
  20. * along with this program; if not, write to the *
  21. * Free Software Foundation, Inc., *
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  23. ***************************************************************************/
  24. #include "dcc_stdio.h"
  25. #define TARGET_REQ_TRACEMSG 0x00
  26. #define TARGET_REQ_DEBUGMSG_ASCII 0x01
  27. #define TARGET_REQ_DEBUGMSG_HEXMSG(size) (0x01 | ((size & 0xff) << 8))
  28. #define TARGET_REQ_DEBUGCHAR 0x02
  29. #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)
  30. /* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel
  31. * DCRDR[7:0] is used by target for status
  32. * DCRDR[15:8] is used by target for write buffer
  33. * DCRDR[23:16] is used for by host for status
  34. * DCRDR[31:24] is used for by host for write buffer */
  35. #define NVIC_DBG_DATA_R (*((volatile unsigned short *)0xE000EDF8))
  36. #define BUSY 1
  37. void dbg_write(unsigned long dcc_data)
  38. {
  39. int len = 4;
  40. while (len--)
  41. {
  42. /* wait for data ready */
  43. while (NVIC_DBG_DATA_R & BUSY);
  44. /* write our data and set write flag - tell host there is data*/
  45. NVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);
  46. dcc_data >>= 8;
  47. }
  48. }
  49. #elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)
  50. void dbg_write(unsigned long dcc_data)
  51. {
  52. unsigned long dcc_status;
  53. do {
  54. asm volatile("mrc p14, 0, %0, c0, c0" : "=r" (dcc_status));
  55. } while (dcc_status & 0x2);
  56. asm volatile("mcr p14, 0, %0, c1, c0" : : "r" (dcc_data));
  57. }
  58. #else
  59. #error unsupported target
  60. #endif
  61. void dbg_trace_point(unsigned long number)
  62. {
  63. dbg_write(TARGET_REQ_TRACEMSG | (number << 8));
  64. }
  65. void dbg_write_u32(const unsigned long *val, long len)
  66. {
  67. dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));
  68. while (len > 0)
  69. {
  70. dbg_write(*val);
  71. val++;
  72. len--;
  73. }
  74. }
  75. void dbg_write_u16(const unsigned short *val, long len)
  76. {
  77. unsigned long dcc_data;
  78. dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));
  79. while (len > 0)
  80. {
  81. dcc_data = val[0]
  82. | ((len > 1) ? val[1] << 16: 0x0000);
  83. dbg_write(dcc_data);
  84. val += 2;
  85. len -= 2;
  86. }
  87. }
  88. void dbg_write_u8(const unsigned char *val, long len)
  89. {
  90. unsigned long dcc_data;
  91. dbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));
  92. while (len > 0)
  93. {
  94. dcc_data = val[0]
  95. | ((len > 1) ? val[1] << 8 : 0x00)
  96. | ((len > 2) ? val[2] << 16 : 0x00)
  97. | ((len > 3) ? val[3] << 24 : 0x00);
  98. dbg_write(dcc_data);
  99. val += 4;
  100. len -= 4;
  101. }
  102. }
  103. void dbg_write_str(const char *msg)
  104. {
  105. long len;
  106. unsigned long dcc_data;
  107. for (len = 0; msg[len] && (len < 65536); len++);
  108. dbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));
  109. while (len > 0)
  110. {
  111. dcc_data = msg[0]
  112. | ((len > 1) ? msg[1] << 8 : 0x00)
  113. | ((len > 2) ? msg[2] << 16 : 0x00)
  114. | ((len > 3) ? msg[3] << 24 : 0x00);
  115. dbg_write(dcc_data);
  116. msg += 4;
  117. len -= 4;
  118. }
  119. }
  120. void dbg_write_char(char msg)
  121. {
  122. dbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));
  123. }