cortex_debug.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Copyright (C) 2012 by Ole Reinhardt (ole.reinhardt@embedded-it.de)
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /* Parts taken from
  35. * http://www.opensource.apple.com/source/lldb/lldb-159/source/Plugins/Process/Utility/ARMUtils.h?txt
  36. *
  37. * University of Illinois/NCSA
  38. * Open Source License
  39. *
  40. * Copyright (c) 2010 Apple Inc.
  41. * All rights reserved.
  42. *
  43. * Developed by:
  44. *
  45. * LLDB Team
  46. *
  47. * http://lldb.llvm.org/
  48. *
  49. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  50. * this software and associated documentation files (the "Software"), to deal with
  51. * the Software without restriction, including without limitation the rights to
  52. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  53. * of the Software, and to permit persons to whom the Software is furnished to do
  54. * so, subject to the following conditions:
  55. *
  56. * * Redistributions of source code must retain the above copyright notice,
  57. * this list of conditions and the following disclaimers.
  58. *
  59. * * Redistributions in binary form must reproduce the above copyright notice,
  60. * this list of conditions and the following disclaimers in the
  61. * documentation and/or other materials provided with the distribution.
  62. *
  63. * * Neither the names of the LLDB Team, copyright holders, nor the names of
  64. * its contributors may be used to endorse or promote products derived from
  65. * this Software without specific prior written permission.
  66. *
  67. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  68. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  69. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  70. * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  71. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  72. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
  73. * SOFTWARE.
  74. *
  75. */
  76. /*!
  77. * \file arch/cm3/cmsis/cortex_debug.c
  78. *
  79. * \verbatim
  80. * $Id: cortex_debug.c $
  81. * \endverbatim
  82. */
  83. #include <cfg/arch.h>
  84. #include <sys/types.h>
  85. #include <sys/thread.h>
  86. #include <inttypes.h>
  87. #include <cfg/cortex_debug.h>
  88. #include <arch/cm3/cortex_debug.h>
  89. #if defined (MCU_LPC17xx)
  90. #include <arch/cm3/nxp/lpc17xx_debug_macro.h>
  91. #elif defined (MCU_STM32)
  92. #include <arch/cm3/stm/stm32_debug_macro.h>
  93. #endif
  94. extern void * _evect; /* End of vector table / start of text segment in FLASH */
  95. extern void * _etext; /* Start of constants in FLASH */
  96. #define OPCODE_PUSH_R7 0xB480
  97. #define OPCODE_PUSH_R7_LR 0xB580
  98. #define OPCODE_PUSH_MASK 0xFE00
  99. #define OPCODE_PUSH 0xB400
  100. #define OPCODE_SUB_SP 0xB080
  101. #define OPCODE_SUB_SP_MASK 0xFF80
  102. #define OPCODE_SUB_W_SP 0xF1AD
  103. #define OPCODE_SUB_W_SP_MASK 0xFBEF
  104. #define OPCODE_ADD_R7_SP 0xAF00
  105. #define OPCODE_ADD_R7_SP_MASK 0xFF00
  106. static char *exception_names[6] = {"Default", "NMI", "Hard Fault", "Mem Fault", "Bus Fault", "Usage Fault"};
  107. static void DebugPrint(const char *str)
  108. {
  109. #ifdef DEBUG_MACRO
  110. while (*str != 0) {
  111. if (*str == '\n') DebugPut('\r');
  112. DebugPut(*str);
  113. str++;
  114. }
  115. #endif
  116. }
  117. static void DebugPrintU32Hex(uint32_t val) {
  118. #ifdef DEBUG_MACRO
  119. int i;
  120. for (i = 7; i >= 0; i--) {
  121. register int nibble = (val >> (4 * i)) & 0x0F;
  122. DebugPut(nibble < 10 ? '0' + nibble : 'a' + nibble - 10);
  123. }
  124. #endif
  125. }
  126. static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
  127. {
  128. return (val & ~(0xFFFFFFFF << (msbit + 1))) >> lsbit;
  129. }
  130. static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
  131. {
  132. return bits(val, msbit, msbit);
  133. }
  134. static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
  135. {
  136. uint32_t m = shift % N;
  137. return (val >> m) | (val << (N - m));
  138. }
  139. // (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in)
  140. static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t *carry_out)
  141. {
  142. uint32_t imm32; // the expaned result
  143. const uint32_t i = bit(opcode, 26);
  144. const uint32_t imm3 = bits(opcode, 14, 12);
  145. const uint32_t abcdefgh = bits(opcode, 7, 0);
  146. const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
  147. if (bits(imm12, 11, 10) == 0)
  148. {
  149. switch (bits(imm12, 9, 8)) {
  150. case 0:
  151. imm32 = abcdefgh;
  152. break;
  153. case 1:
  154. imm32 = abcdefgh << 16 | abcdefgh;
  155. break;
  156. case 2:
  157. imm32 = abcdefgh << 24 | abcdefgh << 8;
  158. break;
  159. case 3:
  160. imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
  161. break;
  162. }
  163. *carry_out = carry_in;
  164. }
  165. else
  166. {
  167. const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
  168. imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
  169. *carry_out = bit(imm32, 31);
  170. }
  171. return imm32;
  172. }
  173. static inline uint32_t ThumbExpandImm(uint32_t opcode)
  174. {
  175. // 'carry_in' argument to following function call does not affect the imm32 result.
  176. uint32_t carry_in = 0;
  177. uint32_t carry_out;
  178. return ThumbExpandImm_C(opcode, carry_in, &carry_out);
  179. }
  180. // imm32 = ZeroExtend(i:imm3:imm8, 32)
  181. static inline uint32_t ThumbImm12(uint32_t opcode)
  182. {
  183. const uint32_t i = bit(opcode, 26);
  184. const uint32_t imm3 = bits(opcode, 14, 12);
  185. const uint32_t imm8 = bits(opcode, 7, 0);
  186. const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
  187. return imm12;
  188. }
  189. static inline uint32_t ThumbImm7(uint32_t opcode)
  190. {
  191. return bits(opcode, 6, 0);
  192. }
  193. static inline uint32_t ThumbImm8(uint32_t opcode)
  194. {
  195. return bits(opcode, 7, 0);
  196. }
  197. void CortexRegDump(uint32_t *arg, int exception_type, uint32_t *fp)
  198. {
  199. uint32_t stacked_r0;
  200. uint32_t stacked_r1;
  201. uint32_t stacked_r2;
  202. uint32_t stacked_r3;
  203. uint32_t stacked_r12;
  204. uint32_t stacked_lr;
  205. uint32_t stacked_pc;
  206. uint32_t stacked_psr;
  207. DebugPrint("\n---------------------------------------------------\n");
  208. stacked_r0 = ((uint32_t) arg[0]);
  209. stacked_r1 = ((uint32_t) arg[1]);
  210. stacked_r2 = ((uint32_t) arg[2]);
  211. stacked_r3 = ((uint32_t) arg[3]);
  212. stacked_r12 = ((uint32_t) arg[4]);
  213. stacked_lr = ((uint32_t) arg[5]);
  214. stacked_pc = ((uint32_t) arg[6]);
  215. stacked_psr = ((uint32_t) arg[7]);
  216. DebugPrint("["); DebugPrint(exception_names[exception_type]); DebugPrint(" handler - all numbers in hex]\n");
  217. #if defined(SCB_HFSR_FORCED_Msk)
  218. if (exception_type == 2) {
  219. /* This is a hard fault handler */
  220. if ((SCB->HFSR & SCB_HFSR_FORCED_Msk) != 0) {
  221. DebugPrint("Forced Hard Fault!\n");
  222. }
  223. }
  224. #endif
  225. DebugPrint("\nR0 = 0x"); DebugPrintU32Hex(stacked_r0);
  226. DebugPrint("\nR1 = 0x"); DebugPrintU32Hex(stacked_r1);
  227. DebugPrint("\nR2 = 0x"); DebugPrintU32Hex(stacked_r2);
  228. DebugPrint("\nR3 = 0x"); DebugPrintU32Hex(stacked_r3);
  229. DebugPrint("\nR12 = 0x"); DebugPrintU32Hex(stacked_r12);
  230. DebugPrint("\nLR [R14] = 0x"); DebugPrintU32Hex(stacked_lr);
  231. DebugPrint("\nPC [R15] = 0x"); DebugPrintU32Hex(stacked_pc);
  232. DebugPrint("\nPSR = 0x"); DebugPrintU32Hex(stacked_psr);
  233. DebugPrint("\nBFAR = 0x"); DebugPrintU32Hex(*((volatile unsigned long *)(0xE000ED38)));
  234. DebugPrint("\nCFSR = 0x"); DebugPrintU32Hex(*((volatile unsigned long *)(0xE000ED28)));
  235. DebugPrint("\nHFSR = 0x"); DebugPrintU32Hex(*((volatile unsigned long *)(0xE000ED2C)));
  236. DebugPrint("\nDFSR = 0x"); DebugPrintU32Hex(*((volatile unsigned long *)(0xE000ED30)));
  237. DebugPrint("\nAFSR = 0x"); DebugPrintU32Hex(*((volatile unsigned long *)(0xE000ED3C)));
  238. DebugPrint("\nSCB_SHCSR = 0x"); DebugPrintU32Hex(SCB->SHCSR);
  239. DebugPrint("\n---------------------------------------------------\n");
  240. #ifdef DEBUG_BACKTRACE
  241. /* These are experimental enhancements to the exception handler which
  242. * allow to print out a stack dump and a call trace.
  243. *
  244. * For these extensions to work properly, we need frame pointer support.
  245. * Compiler optimisation must be disabled (-O0)
  246. *
  247. * At a minimum, we need the following compiler flags to be enabled:
  248. *
  249. * -O0 -mtpcs-frame -mtpcs-leaf-frame -fno-omit-frame-pointer
  250. *
  251. * Please consider this code highly experimental. Even if the frame pointer
  252. * support is enabled in the compiler, gcc does not create correct frame
  253. * pointers when compiling for CortexM. Instead of base address of the
  254. * current stack frame, the framepointer register (r7 for CortexM) holds
  255. * the stack pointer address after allocating stack for local variables etc...
  256. * This value is quite useless, as we need to know the start of the stack
  257. * frame, where the lr register value was pushed.
  258. *
  259. * Usually the following function entry code is generated (with a few
  260. * variations):
  261. *
  262. * push {r7, lr}
  263. * sub sp, #32
  264. * add r7, sp, #0
  265. *
  266. * The below code now trys to detect and decode these three instructions.
  267. * The code searches backwards from the last known PC value.
  268. * If the above instructions are found, it is assumed, that this is the
  269. * entry of the current function, and the instructions are decoded
  270. * to back calculate the real stack pointer value at entry into the function.
  271. *
  272. * In the above example:
  273. *
  274. * The "frame pointer" is r7. We have to substract 0 and add 32 to the
  275. * framepointer to get the stack pointer value right after pushing LR to
  276. * the stack. We then read LR from the stack memory to get the address
  277. * where the current functions has been called from. Further more we read
  278. * R7 from the stack to also get the next "frame pointer".
  279. * The above steps are repeated until we reached the base of the current
  280. * stack or got an invalid stack pointer value.
  281. *
  282. * The backtrace only works for functions that are compiled with exactly
  283. * the above compiler options. E.g. it will not work for included
  284. * binary only libraries like newlib.
  285. */
  286. uint32_t offs;
  287. uint32_t *sp;
  288. uint16_t *pc;
  289. uint16_t *lr;
  290. uint16_t *saved_pc;
  291. DebugPrint("\nStack:\n\n");
  292. /* Print out stack, beginning with the current frame pointer. Frame pointer
  293. * (r7) is only available, if compiled with above compiler options.
  294. */
  295. sp = fp;
  296. for (offs = 0; offs < 128; offs += 4) {
  297. DebugPrintU32Hex((uint32_t)sp); DebugPrint(": ");
  298. DebugPrintU32Hex(*(sp++)); DebugPut(' '); DebugPrintU32Hex(*(sp++)); DebugPut(' '); DebugPrintU32Hex(*(sp++)); DebugPut(' '); DebugPrintU32Hex(*(sp++)); DebugPut(' ');
  299. DebugPrint("\n");
  300. }
  301. DebugPrint("\n---------------------------------------------------\n");
  302. /* We try to trace back the last function calls and print out a stack trace */
  303. DebugPrint("\nCall Trace:\n\n");
  304. DebugPrint("\nInitial fp: 0x");DebugPrintU32Hex((uint32_t) fp); DebugPrint("\n\n");
  305. pc = (uint16_t*)(stacked_pc & 0xFFFFFFFE);
  306. if (fp <= (uint32_t*)runningThread->td_memory) {
  307. DebugPrint("\nInvalid frame pointer! Out of thread stack bounds:\n\n");
  308. DebugPrint("PC: ");DebugPrintU32Hex((uint32_t)pc); DebugPrint("\n");
  309. DebugPrint("FP: ");DebugPrintU32Hex((uint32_t)fp); DebugPrint("\n");
  310. DebugPrint("Thread stack base: ");DebugPrintU32Hex((uint32_t)runningThread->td_memory); DebugPrint("\n");
  311. } else {
  312. DebugPrint("\n Addr: Function: Offset: Frame pointer:\n");
  313. lr = pc;
  314. int count = 0;
  315. while (((uint32_t)pc > (stacked_pc & 0xF8000000) + 2) &&
  316. ((uint32_t)fp > 0) && (fp > (uint32_t*)runningThread->td_memory)) {
  317. /* Probe for the instruction entry "signature": push {r7, lr, more regs}; sub sp, #x; add r7, sp, #y; */
  318. if ((((*pc & OPCODE_PUSH_MASK) == OPCODE_PUSH) && ((*(pc + 1) & OPCODE_SUB_SP_MASK) == OPCODE_SUB_SP) && ((*(pc + 2) & OPCODE_ADD_R7_SP_MASK) == OPCODE_ADD_R7_SP)) ||
  319. (((*pc & OPCODE_PUSH_MASK) == OPCODE_PUSH) && ((*(pc + 1) & OPCODE_SUB_W_SP_MASK) == OPCODE_SUB_W_SP) && ((*(pc + 3) & OPCODE_ADD_R7_SP_MASK) == OPCODE_ADD_R7_SP)) ||
  320. (((*pc & OPCODE_PUSH_MASK) == OPCODE_PUSH) && ((*(pc + 1) & OPCODE_ADD_R7_SP_MASK) == OPCODE_ADD_R7_SP))) {
  321. /* Found the function entry. Minimum R7 is pushed. LR only on node functions */
  322. DebugPrint("\n 0x"); DebugPrintU32Hex((uint32_t) lr); DebugPrint(" = [0x"); DebugPrintU32Hex((uint32_t) pc); DebugPrint("] + 0x"); DebugPrintU32Hex((uint32_t) (lr - pc) * 2); DebugPrint(": ");
  323. /* Increment pc to read next opcode. Very likely 'sub pc, #x' */
  324. saved_pc = pc;
  325. pc ++;
  326. if ((*pc & OPCODE_SUB_SP_MASK) == OPCODE_SUB_SP) {
  327. /* sub pc, #x */
  328. DebugPrint(" Sub: 0x"); DebugPrintU32Hex(ThumbImm7(*pc)); DebugPrint("\n");
  329. fp = fp + ThumbImm7(*pc); /* Add value which was substracted and function entry + 1, for the LR and the FP address (R7) itself */
  330. pc ++;
  331. } else
  332. if ((*pc & OPCODE_SUB_W_SP_MASK) == OPCODE_SUB_SP) {
  333. /* sub.w sp, sp, #x */
  334. fp = fp + ThumbExpandImm((uint32_t)*pc << 16 | (uint32_t)*(pc + 1)) / sizeof(uint32_t);
  335. pc += 2;
  336. }
  337. if ((*pc & OPCODE_ADD_R7_SP_MASK) == OPCODE_ADD_R7_SP) {
  338. /* add r7, sp, #x */
  339. fp = fp - ThumbImm8(*pc);
  340. DebugPrint(" fp: 0x");
  341. DebugPrintU32Hex((uint32_t) fp);
  342. // if (*(pc - 2) == OPCODE_PUSH_R7) {
  343. if (*(saved_pc) == OPCODE_PUSH_R7) {
  344. /* Set pc to stacked_lr value, which is the calling function */
  345. pc = (uint16_t*)(stacked_lr & 0xFFFFFFFE);
  346. } else {
  347. pc = (uint16_t*)((*(fp + 1)) & 0xFFFFFFFE);
  348. }
  349. lr = pc;
  350. fp = (uint32_t*)*fp;
  351. count ++;
  352. if (((uint32_t)fp == 0) || (fp < (uint32_t*)runningThread->td_memory)) {
  353. DebugPrint("\n\nInvalid next frame pointer! Out of thread stack bounds:");
  354. DebugPrint("\nfp: 0x"); DebugPrintU32Hex((uint32_t) fp);
  355. DebugPrint("\npc: 0x"); DebugPrintU32Hex((uint32_t) pc);
  356. DebugPrint("\n");
  357. }
  358. }
  359. }
  360. pc --;
  361. }
  362. }
  363. #endif
  364. DebugPrint("\n\nHalted...");
  365. __asm("BKPT #0\n") ; // Break into the debugger
  366. while(1);
  367. }