You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/03/07 10:36:04 UTC

[incubator-nuttx] 01/02: arch/armv7-m: Adds dwt helper functions for controlling watchpoints in code.

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit afd6ad4ff571f1bb4a4dcc88f24769fc9d2f57a1
Author: Anthony Merlino <an...@vergeaero.com>
AuthorDate: Sat Mar 6 22:36:42 2021 -0500

    arch/armv7-m: Adds dwt helper functions for controlling watchpoints in code.
    
    In scenarios where there is suspicion that someone might be touching your data when you don't expect, you can setup a watchpoint, and then guard accesses that you know are valid. If the debugger halts due to the watchpoint, you'll see where the unexpected access is coming from.
---
 arch/arm/src/armv7-m/dwt.h | 139 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)

diff --git a/arch/arm/src/armv7-m/dwt.h b/arch/arm/src/armv7-m/dwt.h
index 6320d26..68067c3 100644
--- a/arch/arm/src/armv7-m/dwt.h
+++ b/arch/arm/src/armv7-m/dwt.h
@@ -63,6 +63,12 @@
 #ifndef __ARCH_ARM_SRC_ARMV7_M_DWT_H
 #define __ARCH_ARM_SRC_ARMV7_M_DWT_H
 
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "arm_arch.h"
+
 /***********************************************************************************************
  * Pre-processor Definitions
  ***********************************************************************************************/
@@ -95,6 +101,12 @@
 #define DWT_COMP3                    (DWT_BASE + 0x0050)  /* Comparator Register 3 */
 #define DWT_MASK3                    (DWT_BASE + 0x0054)  /* Mask Register 3 */
 #define DWT_FUNCTION3                (DWT_BASE + 0x0058)  /* Function Register 3 */
+#define DWT_LAR                      (DWT_BASE + 0x0FB0)  /* Lock Access Register */
+
+#define DWT_LAR_ACCESS               (0xC5ACCE55) /* Lock Access Magic Value */
+
+#define DWT_GRANT_ACCESS()           (putreg32(DWT_LAR_ACCESS, DWT_LAR))
+#define DWT_REVOKE_ACCESS()          (putreg32(~DWT_LAR_ACCESS, DWT_LAR))
 
 /* DWT Register Bit Field Definitions **********************************************************/
 
@@ -188,4 +200,131 @@
 #define DWT_FUNCTION_FUNCTION_SHIFT   0
 #define DWT_FUNCTION_FUNCTION_MASK    (0xful << DWT_FUNCTION_FUNCTION_SHIFT)
 
+#define DWT_FUNCTION_WATCHPOINT_RO    (0x05ul << DWT_FUNCTION_FUNCTION_SHIFT)
+#define DWT_FUNCTION_WATCHPOINT_WO    (0x06ul << DWT_FUNCTION_FUNCTION_SHIFT)
+#define DWT_FUNCTION_WATCHPOINT_RW    (0x07ul << DWT_FUNCTION_FUNCTION_SHIFT)
+
+#define DWT_DATAVSIZE_BYTE            (0x00ul << DWT_FUNCTION_DATAVSIZE_SHIFT)
+#define DWT_DATAVSIZE_HALFWORD        (0x01ul << DWT_FUNCTION_DATAVSIZE_SHIFT)
+#define DWT_DATAVSIZE_WORD            (0x02ul << DWT_FUNCTION_DATAVSIZE_SHIFT)
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+static inline void dwt_comparator_setup(int compnum, uint32_t comp,
+                                        uint32_t mask, uint32_t func)
+{
+  DWT_GRANT_ACCESS();
+  switch (compnum)
+    {
+        case 0:
+            putreg32(comp, DWT_COMP0); 
+            putreg32(mask, DWT_MASK0); 
+            putreg32(func, DWT_FUNCTION0); 
+            break;
+        case 1:
+            putreg32(comp, DWT_COMP1); 
+            putreg32(mask, DWT_MASK1); 
+            putreg32(func, DWT_FUNCTION1); 
+            break;
+        case 2:
+            putreg32(comp, DWT_COMP2); 
+            putreg32(mask, DWT_MASK2); 
+            putreg32(func, DWT_FUNCTION2); 
+            break;
+        case 3:
+            putreg32(comp, DWT_COMP3); 
+            putreg32(mask, DWT_MASK3); 
+            putreg32(func, DWT_FUNCTION3); 
+            break;
+        default:
+            break;
+    }
+  DWT_REVOKE_ACCESS();
+}
+
+static inline void dwt_comparator_reset(int compnum)
+{
+  DWT_GRANT_ACCESS();
+  switch (compnum)
+    {
+        case 0:
+            putreg32(0, DWT_COMP0); 
+            putreg32(0, DWT_MASK0); 
+            putreg32(0, DWT_FUNCTION0); 
+            break;
+        case 1:
+            putreg32(0, DWT_COMP1); 
+            putreg32(0, DWT_MASK1); 
+            putreg32(0, DWT_FUNCTION1); 
+            break;
+        case 2:
+            putreg32(0, DWT_COMP2); 
+            putreg32(0, DWT_MASK2); 
+            putreg32(0, DWT_FUNCTION2); 
+            break;
+        case 3:
+            putreg32(0, DWT_COMP3); 
+            putreg32(0, DWT_MASK3); 
+            putreg32(0, DWT_FUNCTION3); 
+            break;
+        default:
+            break;
+    }
+  DWT_REVOKE_ACCESS();
+}
+
+static inline uint32_t dwt_comparator_block(int compnum)
+{
+  uint32_t funcval = 0;
+  DWT_GRANT_ACCESS();
+  switch (compnum)
+    {
+        case 0:
+            funcval = getreg32(DWT_FUNCTION0); 
+            putreg32(0, DWT_FUNCTION0); 
+            break;
+        case 1:
+            funcval = getreg32(DWT_FUNCTION1); 
+            putreg32(0, DWT_FUNCTION1); 
+            break;
+        case 2:
+            funcval = getreg32(DWT_FUNCTION2); 
+            putreg32(0, DWT_FUNCTION2); 
+            break;
+        case 3:
+            funcval = getreg32(DWT_FUNCTION3); 
+            putreg32(0, DWT_FUNCTION3); 
+            break;
+        default:
+            break;
+    }
+  DWT_REVOKE_ACCESS();
+  return funcval;
+}
+
+static inline void dwt_comparator_restore(int compnum, uint32_t func)
+{
+  DWT_GRANT_ACCESS();
+  switch (compnum)
+    {
+        case 0:
+            putreg32(func, DWT_FUNCTION0); 
+            break;
+        case 1:
+            putreg32(func, DWT_FUNCTION1); 
+            break;
+        case 2:
+            putreg32(func, DWT_FUNCTION2); 
+            break;
+        case 3:
+            putreg32(func, DWT_FUNCTION3); 
+            break;
+        default:
+            break;
+    }
+  DWT_REVOKE_ACCESS();
+}
+
 #endif /* __ARCH_ARM_SRC_ARMV7_M_DWT_H */