Browse Source

[2.0.x] Move backtrace to a shared location (#10237)

- And implement the `backtrace()` function call
Eduardo José Tagle 7 years ago
parent
commit
749f19e502

+ 18
- 48
Marlin/src/HAL/HAL_DUE/DebugMonitor_Due.cpp View File

24
 
24
 
25
 #include "../../inc/MarlinConfig.h"
25
 #include "../../inc/MarlinConfig.h"
26
 #include "../../Marlin.h"
26
 #include "../../Marlin.h"
27
-#include "backtrace/unwinder.h"
27
+#include "../../backtrace/unwinder.h"
28
+#include "../../backtrace/unwmemaccess.h"
28
 
29
 
29
 // Debug monitor that dumps to the Programming port all status when
30
 // Debug monitor that dumps to the Programming port all status when
30
 // an exception or WDT timeout happens - And then resets the board
31
 // an exception or WDT timeout happens - And then resets the board
112
   } while (p != &nbrs[0]);
113
   } while (p != &nbrs[0]);
113
 }
114
 }
114
 
115
 
115
-/* Validate address */
116
-static bool validate_addr(uint32_t addr) {
117
-
118
-  // Address must be in SRAM (0x20070000 - 0x20088000)
119
-  if (addr >= 0x20070000 && addr < 0x20088000)
120
-    return true;
121
-
122
-  // Or in FLASH (0x00080000 - 0x00100000)
123
-  if (addr >= 0x00080000 && addr < 0x00100000)
124
-    return true;
125
-
126
-  return false;
127
-}
128
-
129
-static bool UnwReadW(const uint32_t a, uint32_t *v) {
130
-  if (!validate_addr(a))
131
-    return false;
132
-
133
-  *v = *(uint32_t *)a;
134
-  return true;
135
-}
136
-
137
-static bool UnwReadH(const uint32_t a, uint16_t *v) {
138
-  if (!validate_addr(a))
139
-    return false;
140
-
141
-  *v = *(uint16_t *)a;
142
-  return true;
143
-}
144
-
145
-static bool UnwReadB(const uint32_t a, uint8_t *v) {
146
-  if (!validate_addr(a))
147
-    return false;
148
-
149
-  *v = *(uint8_t *)a;
150
-  return true;
151
-}
152
-
153
-
154
 // Dump a backtrace entry
116
 // Dump a backtrace entry
155
 static bool UnwReportOut(void* ctx, const UnwReport* bte) {
117
 static bool UnwReportOut(void* ctx, const UnwReport* bte) {
156
   int* p = (int*)ctx;
118
   int* p = (int*)ctx;
270
 }
232
 }
271
 
233
 
272
 __attribute__((naked)) void NMI_Handler(void) {
234
 __attribute__((naked)) void NMI_Handler(void) {
273
-  __asm volatile (
235
+  __asm__ __volatile__ (
236
+    ".syntax unified        \n"
274
     " tst lr, #4            \n"
237
     " tst lr, #4            \n"
275
     " ite eq                \n"
238
     " ite eq                \n"
276
     " mrseq r0, msp         \n"
239
     " mrseq r0, msp         \n"
282
 }
245
 }
283
 
246
 
284
 __attribute__((naked)) void HardFault_Handler(void) {
247
 __attribute__((naked)) void HardFault_Handler(void) {
285
-  __asm volatile (
248
+  __asm__ __volatile__ (
249
+    ".syntax unified        \n"
286
     " tst lr, #4            \n"
250
     " tst lr, #4            \n"
287
     " ite eq                \n"
251
     " ite eq                \n"
288
     " mrseq r0, msp         \n"
252
     " mrseq r0, msp         \n"
294
 }
258
 }
295
 
259
 
296
 __attribute__((naked)) void MemManage_Handler(void) {
260
 __attribute__((naked)) void MemManage_Handler(void) {
297
-  __asm volatile (
261
+  __asm__ __volatile__ (
262
+    ".syntax unified        \n"
298
     " tst lr, #4            \n"
263
     " tst lr, #4            \n"
299
     " ite eq                \n"
264
     " ite eq                \n"
300
     " mrseq r0, msp         \n"
265
     " mrseq r0, msp         \n"
306
 }
271
 }
307
 
272
 
308
 __attribute__((naked)) void BusFault_Handler(void) {
273
 __attribute__((naked)) void BusFault_Handler(void) {
309
-  __asm volatile (
274
+  __asm__ __volatile__ (
275
+    ".syntax unified        \n"
310
     " tst lr, #4            \n"
276
     " tst lr, #4            \n"
311
     " ite eq                \n"
277
     " ite eq                \n"
312
     " mrseq r0, msp         \n"
278
     " mrseq r0, msp         \n"
318
 }
284
 }
319
 
285
 
320
 __attribute__((naked)) void UsageFault_Handler(void) {
286
 __attribute__((naked)) void UsageFault_Handler(void) {
321
-  __asm volatile (
287
+  __asm__ __volatile__ (
288
+    ".syntax unified        \n"
322
     " tst lr, #4            \n"
289
     " tst lr, #4            \n"
323
     " ite eq                \n"
290
     " ite eq                \n"
324
     " mrseq r0, msp         \n"
291
     " mrseq r0, msp         \n"
330
 }
297
 }
331
 
298
 
332
 __attribute__((naked)) void DebugMon_Handler(void) {
299
 __attribute__((naked)) void DebugMon_Handler(void) {
333
-  __asm volatile (
300
+  __asm__ __volatile__ (
301
+    ".syntax unified        \n"
334
     " tst lr, #4            \n"
302
     " tst lr, #4            \n"
335
     " ite eq                \n"
303
     " ite eq                \n"
336
     " mrseq r0, msp         \n"
304
     " mrseq r0, msp         \n"
343
 
311
 
344
 /* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
312
 /* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
345
 __attribute__((naked)) void WDT_Handler(void) {
313
 __attribute__((naked)) void WDT_Handler(void) {
346
-  __asm volatile (
314
+  __asm__ __volatile__ (
315
+    ".syntax unified        \n"
347
     " tst lr, #4            \n"
316
     " tst lr, #4            \n"
348
     " ite eq                \n"
317
     " ite eq                \n"
349
     " mrseq r0, msp         \n"
318
     " mrseq r0, msp         \n"
355
 }
324
 }
356
 
325
 
357
 __attribute__((naked)) void RSTC_Handler(void) {
326
 __attribute__((naked)) void RSTC_Handler(void) {
358
-  __asm volatile (
327
+  __asm__ __volatile__ (
328
+    ".syntax unified        \n"
359
     " tst lr, #4            \n"
329
     " tst lr, #4            \n"
360
     " ite eq                \n"
330
     " ite eq                \n"
361
     " mrseq r0, msp         \n"
331
     " mrseq r0, msp         \n"

+ 102
- 0
Marlin/src/backtrace/backtrace.cpp View File

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#include "backtrace.h"
24
+
25
+#if defined(__arm__) || defined(__thumb__)
26
+
27
+#include "unwinder.h"
28
+#include "unwmemaccess.h"
29
+#include "../Marlin.h"
30
+
31
+// Dump a backtrace entry
32
+static bool UnwReportOut(void* ctx, const UnwReport* bte) {
33
+  int* p = (int*)ctx;
34
+
35
+  (*p)++;
36
+
37
+  SERIAL_CHAR('#'); SERIAL_PRINT(*p,DEC); SERIAL_ECHOPGM(" : ");
38
+  SERIAL_ECHOPGM(bte->name?bte->name:"unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function,HEX);
39
+  SERIAL_CHAR('+'); SERIAL_PRINT(bte->address - bte->function,DEC);
40
+  SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address,HEX); SERIAL_CHAR('\n');
41
+  return true;
42
+}
43
+
44
+#if defined(UNW_DEBUG)
45
+void UnwPrintf(const char* format, ...) {
46
+  char dest[256];
47
+  va_list argptr;
48
+  va_start(argptr, format);
49
+  vsprintf(dest, format, argptr);
50
+  va_end(argptr);
51
+  TX(&dest[0]);
52
+}
53
+#endif
54
+
55
+/* Table of function pointers for passing to the unwinder */
56
+static const UnwindCallbacks UnwCallbacks = {
57
+  UnwReportOut,
58
+  UnwReadW,
59
+  UnwReadH,
60
+  UnwReadB
61
+#if defined(UNW_DEBUG)
62
+ ,UnwPrintf
63
+#endif
64
+};
65
+
66
+void backtrace(void) {
67
+
68
+  UnwindFrame btf;
69
+  uint32_t sp,lr,pc;
70
+
71
+  // Capture the values of the registers to perform the traceback
72
+  __asm__ __volatile__ (
73
+    " mov %[lrv],lr\n"
74
+    " mov %[spv],sp\n"
75
+    " mov %[pcv],pc\n"
76
+    : [spv]"+r"( sp ),
77
+      [lrv]"+r"( lr ),
78
+      [pcv]"+r"( pc )
79
+    ::
80
+  );
81
+
82
+  // Fill the traceback structure
83
+  btf.sp = sp;
84
+  btf.fp = btf.sp;
85
+  btf.lr = lr;
86
+  btf.pc = pc | 1; // Force Thumb, as CORTEX only support it
87
+
88
+  // Perform a backtrace
89
+  SERIAL_ERROR_START();
90
+  SERIAL_ERRORLNPGM("Backtrace:");
91
+  int ctr = 0;
92
+  UnwindStart(&btf, &UnwCallbacks, &ctr);
93
+}
94
+
95
+#else
96
+
97
+void backtrace(void) {}
98
+
99
+#endif
100
+
101
+
102
+

+ 29
- 0
Marlin/src/backtrace/backtrace.h View File

1
+/**
2
+ * Marlin 3D Printer Firmware
3
+ * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
+ *
5
+ * Based on Sprinter and grbl.
6
+ * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
+ *
8
+ * This program is free software: you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation, either version 3 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
+ *
21
+ */
22
+
23
+#ifndef _BACKTRACE_H_
24
+#define _BACKTRACE_H_
25
+
26
+// Perform a backtrace to the serial port
27
+void backtrace(void);
28
+
29
+#endif

Marlin/src/HAL/HAL_DUE/backtrace/unwarm.c → Marlin/src/backtrace/unwarm.cpp View File

12
  * File Description: Utility functions and glue for ARM unwinding sub-modules.
12
  * File Description: Utility functions and glue for ARM unwinding sub-modules.
13
  **************************************************************************/
13
  **************************************************************************/
14
 
14
 
15
-#ifdef ARDUINO_ARCH_SAM
15
+#if defined(__arm__) || defined(__thumb__)
16
 
16
 
17
 #define MODULE_NAME "UNWARM"
17
 #define MODULE_NAME "UNWARM"
18
 
18
 
19
 #include <stdint.h>
19
 #include <stdint.h>
20
-#include <stdbool.h>
21
 #include <stdio.h>
20
 #include <stdio.h>
22
 #include <stdarg.h>
21
 #include <stdarg.h>
23
 #include <string.h>
22
 #include <string.h>

Marlin/src/HAL/HAL_DUE/backtrace/unwarm.h → Marlin/src/backtrace/unwarm.h View File

54
   /** The origin of the register value.
54
   /** The origin of the register value.
55
    * This is used to track how the value in the register was loaded.
55
    * This is used to track how the value in the register was loaded.
56
    */
56
    */
57
-  RegValOrigin o;
57
+  int o; /* (RegValOrigin) */
58
 } RegData;
58
 } RegData;
59
 
59
 
60
 
60
 
131
  *  Function Prototypes
131
  *  Function Prototypes
132
  **************************************************************************/
132
  **************************************************************************/
133
 
133
 
134
-#ifdef __cplusplus
135
-extern "C" {
136
-#endif
137
-
138
 UnwResult UnwStartArm(UnwState * const state);
134
 UnwResult UnwStartArm(UnwState * const state);
139
 UnwResult UnwStartThumb(UnwState * const state);
135
 UnwResult UnwStartThumb(UnwState * const state);
140
 void UnwInvalidateRegisterFile(RegData *regFile);
136
 void UnwInvalidateRegisterFile(RegData *regFile);
144
 bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg);
140
 bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg);
145
 void UnwMemHashGC(UnwState * const state);
141
 void UnwMemHashGC(UnwState * const state);
146
 
142
 
147
-#ifdef __cplusplus
148
-}
149
-#endif
150
-
151
 #endif /* UNWARM_H */
143
 #endif /* UNWARM_H */
152
 
144
 
153
 /* END OF FILE */
145
 /* END OF FILE */

Marlin/src/HAL/HAL_DUE/backtrace/unwarm_arm.c → Marlin/src/backtrace/unwarm_arm.cpp View File

12
  * File Description: Abstract interpreter for ARM mode.
12
  * File Description: Abstract interpreter for ARM mode.
13
  **************************************************************************/
13
  **************************************************************************/
14
 
14
 
15
-#ifdef ARDUINO_ARCH_SAM
15
+#if defined(__arm__) || defined(__thumb__)
16
 
16
 
17
 #define MODULE_NAME "UNWARM_ARM"
17
 #define MODULE_NAME "UNWARM_ARM"
18
 
18
 
180
       uint8_t        rd = (instr & 0x0000f000) >> 12;
180
       uint8_t        rd = (instr & 0x0000f000) >> 12;
181
       uint16_t operand2 = (instr & 0x00000fff);
181
       uint16_t operand2 = (instr & 0x00000fff);
182
       uint32_t        op2val;
182
       uint32_t        op2val;
183
-      RegValOrigin op2origin;
183
+      int             op2origin;
184
 
184
 
185
       switch(opcode) {
185
       switch(opcode) {
186
         case  0: UnwPrintd4("AND%s r%d,r%d,", S ? "S" : "", rd, rn); break;
186
         case  0: UnwPrintd4("AND%s r%d,r%d,", S ? "S" : "", rd, rn); break;
344
           }
344
           }
345
           else {
345
           else {
346
             state->regData[rd].o = state->regData[rn].o;
346
             state->regData[rd].o = state->regData[rn].o;
347
-            state->regData[rd].o |= op2origin;
347
+            state->regData[rd].o = (RegValOrigin)(state->regData[rd].o | op2origin);
348
           }
348
           }
349
           break;
349
           break;
350
 
350
 
363
 
363
 
364
         case 13: /* MOV: Rd:= Op2 */
364
         case 13: /* MOV: Rd:= Op2 */
365
         case 15: /* MVN: Rd:= NOT Op2 */
365
         case 15: /* MVN: Rd:= NOT Op2 */
366
-          state->regData[rd].o = op2origin;
366
+          state->regData[rd].o = (RegValOrigin) op2origin;
367
           break;
367
           break;
368
       }
368
       }
369
 
369
 

Marlin/src/HAL/HAL_DUE/backtrace/unwarm_thumb.c → Marlin/src/backtrace/unwarm_thumb.cpp View File

12
  * File Description: Abstract interpretation for Thumb mode.
12
  * File Description: Abstract interpretation for Thumb mode.
13
  **************************************************************************/
13
  **************************************************************************/
14
 
14
 
15
-#ifdef ARDUINO_ARCH_SAM
15
+#if defined(__arm__) || defined(__thumb__)
16
 
16
 
17
 #define MODULE_NAME "UNWARM_THUMB"
17
 #define MODULE_NAME "UNWARM_THUMB"
18
 
18
 
243
 
243
 
244
         UnwPrintd3("  r%d = 0x%08x\n", r, state->regData[r].v);
244
         UnwPrintd3("  r%d = 0x%08x\n", r, state->regData[r].v);
245
       }
245
       }
246
-			/*
247
-			 * TBB / TBH
248
-			 */
249
-			else if ((instr & 0xfff0) == 0xe8d0 && (instr2 & 0xffe0) == 0xf000) {
250
-				/* We are only interested in 
251
-				 * the forms 
252
-				 *	TBB [PC, ...]
253
-				 *  TBH [PC, ..., LSL #1]
254
-				 * as those are used by the C compiler to implement
255
-				 * the switch clauses
256
-				 */
257
-				uint8_t rn = instr & 0xf;
258
-				uint8_t rm = instr2 & 0xf;
259
-				bool H = (instr2 & 0x10) ? true : false;
260
-				
261
-				UnwPrintd5("TB%c [r%d,r%d%s]\n", H ? 'H' : 'B', rn, rm, H ? ",LSL #1" : "");				
262
-				
263
-				// We are only interested if the RN is the PC. Let´s choose the 1st destination
264
-				if (rn == 15) {
265
-					if (H) {
266
-						uint16_t rv;
267
-						if(!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) {
268
-							return UNWIND_DREAD_H_FAIL;
269
-						}
270
-						state->regData[15].v += rv * 2;
271
-					} else {
272
-						uint8_t rv;
273
-						if(!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) {
274
-							return UNWIND_DREAD_B_FAIL;
275
-						}
276
-						state->regData[15].v += rv * 2;
277
-					}
278
-				}
279
-			}
246
+      /*
247
+       * TBB / TBH
248
+       */
249
+      else if ((instr & 0xfff0) == 0xe8d0 && (instr2 & 0xffe0) == 0xf000) {
250
+        /* We are only interested in
251
+         * the forms
252
+         *  TBB [PC, ...]
253
+         *  TBH [PC, ..., LSL #1]
254
+         * as those are used by the C compiler to implement
255
+         * the switch clauses
256
+         */
257
+        uint8_t rn = instr & 0xf;
258
+        uint8_t rm = instr2 & 0xf;
259
+        bool H = (instr2 & 0x10) ? true : false;
260
+
261
+        UnwPrintd5("TB%c [r%d,r%d%s]\n", H ? 'H' : 'B', rn, rm, H ? ",LSL #1" : "");
262
+
263
+        // We are only interested if the RN is the PC. Let´s choose the 1st destination
264
+        if (rn == 15) {
265
+          if (H) {
266
+            uint16_t rv;
267
+            if(!state->cb->readH((state->regData[15].v & (~1)) + 2, &rv)) {
268
+              return UNWIND_DREAD_H_FAIL;
269
+            }
270
+            state->regData[15].v += rv * 2;
271
+          } else {
272
+            uint8_t rv;
273
+            if(!state->cb->readB((state->regData[15].v & (~1)) + 2, &rv)) {
274
+              return UNWIND_DREAD_B_FAIL;
275
+            }
276
+            state->regData[15].v += rv * 2;
277
+          }
278
+        }
279
+      }
280
       /*
280
       /*
281
        * Unconditional branch
281
        * Unconditional branch
282
        */
282
        */
408
           UnwPrintd2(" New PC=%x", state->regData[15].v + 2);
408
           UnwPrintd2(" New PC=%x", state->regData[15].v + 2);
409
         }
409
         }
410
       }
410
       }
411
-			/*
412
-			 * PC-relative load
411
+      /*
412
+       * PC-relative load
413
        *  LDR Rd,[PC, #+/-imm]
413
        *  LDR Rd,[PC, #+/-imm]
414
        */
414
        */
415
-			else if((instr & 0xff7f) == 0xf85f) {
416
-				uint8_t  rt    = (instr2 & 0xf000) >> 12;
417
-				uint8_t  imm12 = (instr2 & 0x0fff);
418
-				bool     A     = (instr  & 0x80) ? true : false;
419
-				uint32_t address;
420
-
421
-				/* Compute load address, adding a word to account for prefetch */
422
-				address = (state->regData[15].v & (~0x3)) + 4;
423
-				if (A) address += imm12;
424
-				else address -= imm12;
425
-
426
-				UnwPrintd4("LDR r%d,[PC #%c0x%08x]", rt, A?'+':'-', address);
427
-
428
-				if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
429
-					return UNWIND_DREAD_W_FAIL;
430
-				}
431
-			}
432
-			/*
433
-			 * LDR immediate. 
434
-			 *  We are only interested when destination is PC.
435
-			 *  LDR Rt,[Rn , #n]
436
-			 */
437
-			else if ((instr & 0xfff0) == 0xf8d0) {
438
-				uint8_t     rn = (instr  & 0xf);
439
-				uint8_t     rt = (instr2 & 0xf000) >> 12;
440
-				uint16_t imm12 = (instr2 & 0xfff);
441
-				
442
-				/* If destination is PC and we don't know the source value, then fail */
443
-				if (!M_IsOriginValid(state->regData[rn].o)) {
444
-					state->regData[rt].o = state->regData[rn].o;
445
-				} else {
446
-					uint32_t address = state->regData[rn].v + imm12;
447
-					if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
448
-						return UNWIND_DREAD_W_FAIL;
449
-					}
450
-				}
451
-			}
452
-			/*
453
-			 * LDR immediate
454
-			 *  We are only interested when destination is PC.
455
-			 *  LDR Rt,[Rn , #-n]
456
-			 *  LDR Rt,[Rn], #+/-n]
457
-			 *  LDR Rt,[Rn, #+/-n]!
458
-			 */
459
-			else if ((instr & 0xfff0) == 0xf850 && (instr2 & 0x0800) == 0x0800) {
460
-				uint8_t     rn = (instr  & 0xf);
461
-				uint8_t     rt = (instr2 & 0xf000) >> 12;
462
-				uint16_t  imm8 = (instr2 & 0xff);
463
-				bool         P = (instr2 & 0x400) ? true : false;
464
-				bool         U = (instr2 & 0x200) ? true : false;
465
-				bool         W = (instr2 & 0x100) ? true : false;
466
-				
467
-				if (!M_IsOriginValid(state->regData[rn].o)) {
468
-					state->regData[rt].o = state->regData[rn].o;
469
-				} else {
470
-					uint32_t offaddress = state->regData[rn].v + imm8;
471
-					if (U) offaddress += imm8;
472
-					else offaddress -= imm8;
473
-					
474
-					uint32_t address;
475
-					if (P) {
476
-						address = offaddress;
477
-					} else {
478
-						address = state->regData[rn].v;
479
-					}
480
-					
481
-					if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
482
-						return UNWIND_DREAD_W_FAIL;
483
-					}
484
-					
485
-					if (W) {
486
-						state->regData[rn].v = offaddress;
487
-					}
488
-				}
489
-			}
490
-			/*
491
-			 * LDR (register).
492
-			 *  We are interested in the form
493
-			 *   ldr	Rt, [Rn, Rm, lsl #x]
494
-			 *  Where Rt is PC, Rn value is known, Rm is not known or unknown
495
-			 */
496
-			else if ((instr & 0xfff0) == 0xf850 && (instr2 & 0x0fc0) == 0x0000) {
497
-				uint8_t   rn = (instr  & 0xf);
498
-				uint8_t   rt = (instr2 & 0xf000) >> 12;
499
-				uint8_t   rm = (instr2 & 0xf);
500
-				uint8_t imm2 = (instr2 & 0x30) >> 4;
501
-				
502
-				if (!M_IsOriginValid(state->regData[rn].o) ||
503
-						!M_IsOriginValid(state->regData[rm].o)) {
504
-						
505
-					/* If Rt is PC, and Rn is known, then do an exception and assume
506
-					   Rm equals 0 => This takes the first case in a switch() */
507
-					if (rt == 15 && M_IsOriginValid(state->regData[rn].o)) {
508
-						uint32_t address = state->regData[rn].v;
509
-						if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
510
-							return UNWIND_DREAD_W_FAIL;
511
-						}
512
-					} else {
513
-						/* Propagate unknown value */
514
-						state->regData[rt].o = state->regData[rn].o;
515
-					}
516
-				} else {
517
-					uint32_t address = state->regData[rn].v + (state->regData[rm].v << imm2);
518
-					if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
519
-						return UNWIND_DREAD_W_FAIL;
520
-					}
521
-				}
522
-			}
415
+      else if((instr & 0xff7f) == 0xf85f) {
416
+        uint8_t  rt    = (instr2 & 0xf000) >> 12;
417
+        uint8_t  imm12 = (instr2 & 0x0fff);
418
+        bool     A     = (instr  & 0x80) ? true : false;
419
+        uint32_t address;
420
+
421
+        /* Compute load address, adding a word to account for prefetch */
422
+        address = (state->regData[15].v & (~0x3)) + 4;
423
+        if (A) address += imm12;
424
+        else address -= imm12;
425
+
426
+        UnwPrintd4("LDR r%d,[PC #%c0x%08x]", rt, A?'+':'-', address);
427
+
428
+        if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
429
+          return UNWIND_DREAD_W_FAIL;
430
+        }
431
+      }
432
+      /*
433
+       * LDR immediate.
434
+       *  We are only interested when destination is PC.
435
+       *  LDR Rt,[Rn , #n]
436
+       */
437
+      else if ((instr & 0xfff0) == 0xf8d0) {
438
+        uint8_t     rn = (instr  & 0xf);
439
+        uint8_t     rt = (instr2 & 0xf000) >> 12;
440
+        uint16_t imm12 = (instr2 & 0xfff);
441
+
442
+        /* If destination is PC and we don't know the source value, then fail */
443
+        if (!M_IsOriginValid(state->regData[rn].o)) {
444
+          state->regData[rt].o = state->regData[rn].o;
445
+        } else {
446
+          uint32_t address = state->regData[rn].v + imm12;
447
+          if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
448
+            return UNWIND_DREAD_W_FAIL;
449
+          }
450
+        }
451
+      }
452
+      /*
453
+       * LDR immediate
454
+       *  We are only interested when destination is PC.
455
+       *  LDR Rt,[Rn , #-n]
456
+       *  LDR Rt,[Rn], #+/-n]
457
+       *  LDR Rt,[Rn, #+/-n]!
458
+       */
459
+      else if ((instr & 0xfff0) == 0xf850 && (instr2 & 0x0800) == 0x0800) {
460
+        uint8_t     rn = (instr  & 0xf);
461
+        uint8_t     rt = (instr2 & 0xf000) >> 12;
462
+        uint16_t  imm8 = (instr2 & 0xff);
463
+        bool         P = (instr2 & 0x400) ? true : false;
464
+        bool         U = (instr2 & 0x200) ? true : false;
465
+        bool         W = (instr2 & 0x100) ? true : false;
466
+
467
+        if (!M_IsOriginValid(state->regData[rn].o)) {
468
+          state->regData[rt].o = state->regData[rn].o;
469
+        } else {
470
+          uint32_t offaddress = state->regData[rn].v + imm8;
471
+          if (U) offaddress += imm8;
472
+          else offaddress -= imm8;
473
+
474
+          uint32_t address;
475
+          if (P) {
476
+            address = offaddress;
477
+          } else {
478
+            address = state->regData[rn].v;
479
+          }
480
+
481
+          if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
482
+            return UNWIND_DREAD_W_FAIL;
483
+          }
484
+
485
+          if (W) {
486
+            state->regData[rn].v = offaddress;
487
+          }
488
+        }
489
+      }
490
+      /*
491
+       * LDR (register).
492
+       *  We are interested in the form
493
+       *   ldr  Rt, [Rn, Rm, lsl #x]
494
+       *  Where Rt is PC, Rn value is known, Rm is not known or unknown
495
+       */
496
+      else if ((instr & 0xfff0) == 0xf850 && (instr2 & 0x0fc0) == 0x0000) {
497
+        uint8_t   rn = (instr  & 0xf);
498
+        uint8_t   rt = (instr2 & 0xf000) >> 12;
499
+        uint8_t   rm = (instr2 & 0xf);
500
+        uint8_t imm2 = (instr2 & 0x30) >> 4;
501
+
502
+        if (!M_IsOriginValid(state->regData[rn].o) ||
503
+            !M_IsOriginValid(state->regData[rm].o)) {
504
+
505
+          /* If Rt is PC, and Rn is known, then do an exception and assume
506
+             Rm equals 0 => This takes the first case in a switch() */
507
+          if (rt == 15 && M_IsOriginValid(state->regData[rn].o)) {
508
+            uint32_t address = state->regData[rn].v;
509
+            if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
510
+              return UNWIND_DREAD_W_FAIL;
511
+            }
512
+          } else {
513
+            /* Propagate unknown value */
514
+            state->regData[rt].o = state->regData[rn].o;
515
+          }
516
+        } else {
517
+          uint32_t address = state->regData[rn].v + (state->regData[rm].v << imm2);
518
+          if(!UnwMemReadRegister(state, address, &state->regData[rt])) {
519
+            return UNWIND_DREAD_W_FAIL;
520
+          }
521
+        }
522
+      }
523
       else {
523
       else {
524
         UnwPrintd1("???? (32)");
524
         UnwPrintd1("???? (32)");
525
 
525
 

Marlin/src/HAL/HAL_DUE/backtrace/unwarmbytab.c → Marlin/src/backtrace/unwarmbytab.cpp View File

11
  * for exceptions for debugging purposes in 2018 by Eduardo José Tagle.
11
  * for exceptions for debugging purposes in 2018 by Eduardo José Tagle.
12
  */
12
  */
13
 
13
 
14
-#ifdef ARDUINO_ARCH_SAM
14
+#if defined(__arm__) || defined(__thumb__)
15
 
15
 
16
 #include "unwarmbytab.h"
16
 #include "unwarmbytab.h"
17
 
17
 
19
 #include <string.h>
19
 #include <string.h>
20
 
20
 
21
 /* These symbols point to the unwind index and should be provide by the linker script */
21
 /* These symbols point to the unwind index and should be provide by the linker script */
22
-extern const UnwTabEntry __exidx_start[];
23
-extern const UnwTabEntry __exidx_end[];
22
+extern "C" const UnwTabEntry __exidx_start[];
23
+extern "C" const UnwTabEntry __exidx_end[];
24
 
24
 
25
 /* This prevents the linking of libgcc unwinder code */
25
 /* This prevents the linking of libgcc unwinder code */
26
 void __aeabi_unwind_cpp_pr0(void) {};
26
 void __aeabi_unwind_cpp_pr0(void) {};

Marlin/src/HAL/HAL_DUE/backtrace/unwarmbytab.h → Marlin/src/backtrace/unwarmbytab.h View File

29
   uint32_t insn;
29
   uint32_t insn;
30
 } UnwTabEntry;
30
 } UnwTabEntry;
31
 
31
 
32
-#ifdef __cplusplus
33
-extern "C" {
34
-#endif
35
-
36
 UnwResult UnwindByTableStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data);
32
 UnwResult UnwindByTableStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data);
37
 
33
 
38
-#ifdef __cplusplus
39
-}
40
-#endif
41
-
42
 #endif
34
 #endif
43
 
35
 
44
 /* END OF FILE */
36
 /* END OF FILE */

Marlin/src/HAL/HAL_DUE/backtrace/unwarmmem.c → Marlin/src/backtrace/unwarmmem.cpp View File

12
  * File Description: Implementation of the memory tracking sub-system.
12
  * File Description: Implementation of the memory tracking sub-system.
13
  **************************************************************************/
13
  **************************************************************************/
14
 
14
 
15
-#ifdef ARDUINO_ARCH_SAM
15
+#if defined(__arm__) || defined(__thumb__)
16
 #define MODULE_NAME "UNWARMMEM"
16
 #define MODULE_NAME "UNWARMMEM"
17
 
17
 
18
 #include <stdio.h>
18
 #include <stdio.h>

Marlin/src/HAL/HAL_DUE/backtrace/unwarmmem.h → Marlin/src/backtrace/unwarmmem.h View File

17
 
17
 
18
 #include "unwarm.h"
18
 #include "unwarm.h"
19
 
19
 
20
-#ifdef __cplusplus
21
-extern "C" {
22
-#endif
23
-
24
 bool UnwMemHashRead(MemData * const memData, uint32_t addr, uint32_t * const data, bool * const tracked);
20
 bool UnwMemHashRead(MemData * const memData, uint32_t addr, uint32_t * const data, bool * const tracked);
25
 bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid);
21
 bool UnwMemHashWrite(MemData * const memData, uint32_t addr, uint32_t val, bool valValid);
26
 void UnwMemHashGC(UnwState * const state);
22
 void UnwMemHashGC(UnwState * const state);
27
 
23
 
28
-#ifdef __cplusplus
29
-}
30
-#endif
31
-
32
 #endif
24
 #endif
33
 
25
 

Marlin/src/HAL/HAL_DUE/backtrace/unwinder.c → Marlin/src/backtrace/unwinder.cpp View File

12
  * File Description: Implementation of the interface into the ARM unwinder.
12
  * File Description: Implementation of the interface into the ARM unwinder.
13
  **************************************************************************/
13
  **************************************************************************/
14
 
14
 
15
-#ifdef ARDUINO_ARCH_SAM
15
+#if defined(__arm__) || defined(__thumb__)
16
 
16
 
17
 #define MODULE_NAME "UNWINDER"
17
 #define MODULE_NAME "UNWINDER"
18
 
18
 
23
 #include "unwarmbytab.h"
23
 #include "unwarmbytab.h"
24
 
24
 
25
 /* These symbols point to the unwind index and should be provide by the linker script */
25
 /* These symbols point to the unwind index and should be provide by the linker script */
26
-extern const UnwTabEntry __exidx_start[];
27
-extern const UnwTabEntry __exidx_end[];
26
+extern "C" const UnwTabEntry __exidx_start[];
27
+extern "C" const UnwTabEntry __exidx_end[];
28
 
28
 
29
 // Detect if unwind information is present or not
29
 // Detect if unwind information is present or not
30
 static int HasUnwindTableInfo(void) {
30
 static int HasUnwindTableInfo(void) {

Marlin/src/HAL/HAL_DUE/backtrace/unwinder.h → Marlin/src/backtrace/unwinder.h View File

17
 #define UNWINDER_H
17
 #define UNWINDER_H
18
 
18
 
19
 #include <stdint.h>
19
 #include <stdint.h>
20
-#include <stdbool.h>
21
 
20
 
22
 /** \def UNW_DEBUG
21
 /** \def UNW_DEBUG
23
  * If this define is set, additional information will be produced while
22
  * If this define is set, additional information will be produced while
161
   uint32_t pc;
160
   uint32_t pc;
162
 } UnwindFrame;
161
 } UnwindFrame;
163
 
162
 
164
-#ifdef __cplusplus
165
-extern "C" {
166
-#endif
167
-
168
 /** Start unwinding the current stack.
163
 /** Start unwinding the current stack.
169
  * This will unwind the stack starting at the PC value supplied to in the
164
  * This will unwind the stack starting at the PC value supplied to in the
170
  * link register (i.e. not a normal register) and the stack pointer value
165
  * link register (i.e. not a normal register) and the stack pointer value
177
  */
172
  */
178
 UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data);
173
 UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data);
179
 
174
 
180
-#ifdef __cplusplus
181
-}
182
-#endif
183
-
184
 #endif /* UNWINDER_H */
175
 #endif /* UNWINDER_H */

+ 136
- 0
Marlin/src/backtrace/unwmemaccess.cpp View File

1
+/***************************************************************************
2
+ * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
3
+ * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
4
+ *
5
+ * This program is PUBLIC DOMAIN.
6
+ * This means that there is no copyright and anyone is able to take a copy
7
+ * for free and use it as they wish, with or without modifications, and in
8
+ * any context, commercially or otherwise. The only limitation is that I
9
+ * don't guarantee that the software is fit for any purpose or accept any
10
+ * liability for it's use or misuse - this software is without warranty.
11
+ ***************************************************************************
12
+ * File Description: Utility functions to access memory
13
+ **************************************************************************/
14
+
15
+#if defined(__arm__) || defined(__thumb__)
16
+
17
+#include "unwmemaccess.h"
18
+
19
+/* Validate address */
20
+
21
+#ifdef ARDUINO_ARCH_SAM
22
+// For DUE, valid address ranges are
23
+//  SRAM  (0x20070000 - 0x20088000) (96kb)
24
+//  FLASH (0x00080000 - 0x00100000) (512kb)
25
+//
26
+#define START_SRAM_ADDR   0x20070000
27
+#define END_SRAM_ADDR     0x20088000
28
+#define START_FLASH_ADDR  0x00080000
29
+#define END_FLASH_ADDR    0x00100000
30
+#endif
31
+
32
+#ifdef TARGET_LPC1768
33
+// For LPC1769:
34
+//  SRAM  (0x10000000 - 0x10008000) (32kb)
35
+//  FLASH (0x00000000 - 0x00080000) (512kb)
36
+//
37
+#define START_SRAM_ADDR   0x10000000
38
+#define END_SRAM_ADDR     0x10008000
39
+#define START_FLASH_ADDR  0x00000000
40
+#define END_FLASH_ADDR    0x00080000
41
+#endif
42
+
43
+#if 0
44
+// For STM32F103CBT6
45
+//  SRAM  (0x20000000 - 0x20005000) (20kb)
46
+//  FLASH (0x00000000 - 0x00020000) (128kb)
47
+//
48
+#define START_SRAM_ADDR   0x20000000
49
+#define END_SRAM_ADDR     0x20005000
50
+#define START_FLASH_ADDR  0x00000000
51
+#define END_FLASH_ADDR    0x00020000
52
+#endif
53
+
54
+#ifdef __STM32F1__
55
+// For STM32F103ZET6/STM32F103VET6
56
+//  SRAM  (0x20000000 - 0x20010000) (64kb)
57
+//  FLASH (0x00000000 - 0x00080000) (512kb)
58
+//
59
+#define START_SRAM_ADDR   0x20000000
60
+#define END_SRAM_ADDR     0x20010000
61
+#define START_FLASH_ADDR  0x00000000
62
+#define END_FLASH_ADDR    0x00080000
63
+#endif
64
+
65
+#ifdef STM32F7
66
+// For STM32F765 in BORG
67
+//  SRAM  (0x20000000 - 0x20080000) (512kb)
68
+//  FLASH (0x08000000 - 0x08100000) (1024kb)
69
+//
70
+#define START_SRAM_ADDR   0x20000000
71
+#define END_SRAM_ADDR     0x20080000
72
+#define START_FLASH_ADDR  0x08000000
73
+#define END_FLASH_ADDR    0x08100000
74
+#endif
75
+
76
+#ifdef __MK64FX512__
77
+// For MK64FX512 in TEENSY 3.5
78
+//  SRAM  (0x1FFF0000 - 0x20020000) (192kb)
79
+//  FLASH (0x00000000 - 0x00080000) (512kb)
80
+//
81
+#define START_SRAM_ADDR   0x1FFF0000
82
+#define END_SRAM_ADDR     0x20020000
83
+#define START_FLASH_ADDR  0x00000000
84
+#define END_FLASH_ADDR    0x00080000
85
+#endif
86
+
87
+#ifdef __MK66FX1M0__
88
+// For MK66FX1M0 in TEENSY 3.6
89
+//  SRAM  (0x1FFF0000 - 0x20030000) (256kb)
90
+//  FLASH (0x00000000 - 0x00140000) (1.25Mb)
91
+//
92
+#define START_SRAM_ADDR   0x1FFF0000
93
+#define END_SRAM_ADDR     0x20030000
94
+#define START_FLASH_ADDR  0x00000000
95
+#define END_FLASH_ADDR    0x00140000
96
+#endif
97
+
98
+static bool validate_addr(uint32_t addr) {
99
+
100
+  // Address must be in SRAM range
101
+  if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
102
+    return true;
103
+
104
+  // Or in FLASH range
105
+  if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
106
+    return true;
107
+
108
+  return false;
109
+}
110
+
111
+bool UnwReadW(const uint32_t a, uint32_t *v) {
112
+  if (!validate_addr(a))
113
+    return false;
114
+
115
+  *v = *(uint32_t *)a;
116
+  return true;
117
+}
118
+
119
+bool UnwReadH(const uint32_t a, uint16_t *v) {
120
+  if (!validate_addr(a))
121
+    return false;
122
+
123
+  *v = *(uint16_t *)a;
124
+  return true;
125
+}
126
+
127
+bool UnwReadB(const uint32_t a, uint8_t *v) {
128
+  if (!validate_addr(a))
129
+    return false;
130
+
131
+  *v = *(uint8_t *)a;
132
+  return true;
133
+}
134
+
135
+#endif
136
+

+ 26
- 0
Marlin/src/backtrace/unwmemaccess.h View File

1
+/***************************************************************************
2
+ * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
3
+ * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
4
+ *
5
+ * This program is PUBLIC DOMAIN.
6
+ * This means that there is no copyright and anyone is able to take a copy
7
+ * for free and use it as they wish, with or without modifications, and in
8
+ * any context, commerically or otherwise. The only limitation is that I
9
+ * don't guarantee that the software is fit for any purpose or accept any
10
+ * liablity for it's use or misuse - this software is without warranty.
11
+ ***************************************************************************
12
+ * File Description: Utility functions to access memory
13
+ **************************************************************************/
14
+
15
+#ifndef UNWMEMACCESS_H
16
+#define UNWMEMACCESS_H
17
+
18
+#include "unwarm.h"
19
+#include <stdint.h>
20
+
21
+bool UnwReadW(const uint32_t a, uint32_t *v);
22
+bool UnwReadH(const uint32_t a, uint16_t *v);
23
+bool UnwReadB(const uint32_t a, uint8_t *v);
24
+
25
+#endif
26
+

Loading…
Cancel
Save