W-M-R commented on code in PR #15616:
URL: https://github.com/apache/nuttx/pull/15616#discussion_r1924632306


##########
arch/arm/src/armv7-a/arm_dbgmonitor.c:
##########
@@ -0,0 +1,767 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_dbgmonitor.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/* Debug architecture numbers. */
+
+#define ARM_DEBUG_ARCH_RESERVED  0  /* In case of ptrace ABI updates. */
+#define ARM_DEBUG_ARCH_V6        1
+#define ARM_DEBUG_ARCH_V6_1      2
+#define ARM_DEBUG_ARCH_V7_ECP14  3
+#define ARM_DEBUG_ARCH_V7_MM     4
+#define ARM_DEBUG_ARCH_V7_1      5
+#define ARM_DEBUG_ARCH_V8        6
+#define ARM_DEBUG_ARCH_V8_1      7
+#define ARM_DEBUG_ARCH_V8_2      8
+#define ARM_DEBUG_ARCH_V8_4      9
+
+/* Breakpoint */
+
+#define ARM_BREAKPOINT_EXECUTE   0
+
+/* Watchpoints */
+
+#define ARM_BREAKPOINT_LOAD      1
+#define ARM_BREAKPOINT_STORE     2
+#define ARM_FSR_ACCESS_MASK      (1 << 11)
+
+/* Privilege Levels */
+
+#define ARM_BREAKPOINT_PRIV      1
+#define ARM_BREAKPOINT_USER      2
+
+/* Lengths */
+
+#define ARM_BREAKPOINT_LEN_1     0x1
+#define ARM_BREAKPOINT_LEN_2     0x3
+#define ARM_BREAKPOINT_LEN_4     0xf
+#define ARM_BREAKPOINT_LEN_8     0xff
+
+/* Limits */
+
+#define ARM_MAX_BREAKPOINT       16
+#define ARM_MAX_WATCHPOINT       16
+
+/* DSCR method of entry bits. */
+
+#define ARM_DSCR_MOE(x)             ((x >> 2) & 0xf)
+#define ARM_ENTRY_BREAKPOINT        0x1
+#define ARM_ENTRY_ASYNC_WATCHPOINT  0x2
+#define ARM_ENTRY_CFI_BREAKPOINT    0x3
+#define ARM_ENTRY_SYNC_WATCHPOINT   0xa
+
+/* DSCR monitor/halting bits. */
+
+#define ARM_DSCR_HDBGEN             (1 << 14)
+#define ARM_DSCR_MDBGEN             (1 << 15)
+
+/* OSLSR os lock model bits */
+
+#define ARM_OSLSR_OSLM0             (1 << 0)
+
+/* opcode2 numbers for the co-processor instructions. */
+
+#define ARM_OP2_BVR                 4
+#define ARM_OP2_BCR                 5
+#define ARM_OP2_WVR                 6
+#define ARM_OP2_WCR                 7
+
+/* Base register numbers for the debug registers. */
+
+#define ARM_BASE_BVR                64
+#define ARM_BASE_BCR                80
+#define ARM_BASE_WVR                96
+#define ARM_BASE_WCR                112
+
+/* Accessor macros for the debug registers. */
+#define ARM_DBG_READ(N, M, OP2, VAL) \
+  do { \
+    asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL)); \
+  } while (0)
+
+#define ARM_DBG_WRITE(N, M, OP2, VAL) \
+  do { \
+    asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL)); \
+  } while (0)
+
+#define READ_WB_REG_CASE(OP2, M, VAL)    \
+  case ((OP2 << 4) + M):                 \
+    ARM_DBG_READ(c0, c ## M, OP2, VAL);  \
+    break
+
+#define WRITE_WB_REG_CASE(OP2, M, VAL)   \
+  case ((OP2 << 4) + M):                 \
+    ARM_DBG_WRITE(c0, c ## M, OP2, VAL); \
+    break
+
+#define GEN_READ_WB_REG_CASES(OP2, VAL) \
+  READ_WB_REG_CASE(OP2, 0, VAL);    \
+  READ_WB_REG_CASE(OP2, 1, VAL);    \
+  READ_WB_REG_CASE(OP2, 2, VAL);    \
+  READ_WB_REG_CASE(OP2, 3, VAL);    \
+  READ_WB_REG_CASE(OP2, 4, VAL);    \
+  READ_WB_REG_CASE(OP2, 5, VAL);    \
+  READ_WB_REG_CASE(OP2, 6, VAL);    \
+  READ_WB_REG_CASE(OP2, 7, VAL);    \
+  READ_WB_REG_CASE(OP2, 8, VAL);    \
+  READ_WB_REG_CASE(OP2, 9, VAL);    \
+  READ_WB_REG_CASE(OP2, 10, VAL);   \
+  READ_WB_REG_CASE(OP2, 11, VAL);   \
+  READ_WB_REG_CASE(OP2, 12, VAL);   \
+  READ_WB_REG_CASE(OP2, 13, VAL);   \
+  READ_WB_REG_CASE(OP2, 14, VAL);   \
+  READ_WB_REG_CASE(OP2, 15, VAL)
+
+#define GEN_WRITE_WB_REG_CASES(OP2, VAL) \
+  WRITE_WB_REG_CASE(OP2, 0, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 1, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 2, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 3, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 4, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 5, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 6, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 7, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 8, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 9, VAL);     \
+  WRITE_WB_REG_CASE(OP2, 10, VAL);    \
+  WRITE_WB_REG_CASE(OP2, 11, VAL);    \
+  WRITE_WB_REG_CASE(OP2, 12, VAL);    \
+  WRITE_WB_REG_CASE(OP2, 13, VAL);    \
+  WRITE_WB_REG_CASE(OP2, 14, VAL);    \
+  WRITE_WB_REG_CASE(OP2, 15, VAL)
+
+/****************************************************************************
+ * Private Type
+ ****************************************************************************/
+
+struct arch_hw_breakpoint_ctrl
+{
+  uint32_t __reserved  : 9,
+  mismatch  : 1,
+            : 9,
+  len       : 8,
+  type      : 2,
+  privilege : 2,
+  enabled   : 1;
+};
+
+struct arch_hw_breakpoint
+{
+  uint32_t  address;
+  uint32_t  trigger;
+  struct    arch_hw_breakpoint_ctrl step_ctrl;
+  struct    arch_hw_breakpoint_ctrl ctrl;
+};
+
+struct arch_debug_s
+{
+  int              type;
+  uint32_t         addr;
+  size_t           size;
+  debug_callback_t callback;
+  void             *arg;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Number of BRP/WRP registers on this CPU. */
+
+static int g_breakpoint_num;
+static int g_watchpoint_num;
+
+/* Maximum supported watchpoint length. */
+
+static uint8_t g_max_watchpoint_len;
+
+static struct arch_debug_s g_breakpoints[ARM_MAX_BREAKPOINT];
+static struct arch_debug_s g_watchpoints[ARM_MAX_WATCHPOINT];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t read_wb_reg(int n)
+{
+  uint32_t val = 0;
+
+  switch (n)
+    {
+      GEN_READ_WB_REG_CASES(ARM_OP2_BVR, val);
+      GEN_READ_WB_REG_CASES(ARM_OP2_BCR, val);
+      GEN_READ_WB_REG_CASES(ARM_OP2_WVR, val);
+      GEN_READ_WB_REG_CASES(ARM_OP2_WCR, val);
+      default:
+        binfo("attempt to read from unknown breakpoint register %d\n", n);
+    }
+
+  return val;
+}
+
+static void write_wb_reg(int n, uint32_t val)
+{
+  switch (n)
+    {
+      GEN_WRITE_WB_REG_CASES(ARM_OP2_BVR, val);
+      GEN_WRITE_WB_REG_CASES(ARM_OP2_BCR, val);
+      GEN_WRITE_WB_REG_CASES(ARM_OP2_WVR, val);
+      GEN_WRITE_WB_REG_CASES(ARM_OP2_WCR, val);
+      default:
+        binfo("attempt to write to unknown breakpoint register %d\n", n);
+    }
+}
+
+static uint32_t encode_ctrl_reg(struct arch_hw_breakpoint_ctrl *ctrl)
+{
+  return (ctrl->mismatch << 22) | (ctrl->len << 5) | (ctrl->type << 3) |
+    (ctrl->privilege << 1) | ctrl->enabled;
+}
+
+/* Determine debug architecture. */
+
+static uint8_t get_debug_arch(void)
+{
+  uint32_t didr;
+
+  /* Do we implement the extended CPUID interface? */
+
+  if (((up_read_cpuid() >> 16) & 0xf) != 0xf)
+    {
+      binfo("CPUID feature registers not supported. "
+            "Assuming v6 debug is present.\n");
+      return ARM_DEBUG_ARCH_V6;
+    }
+
+  ARM_DBG_READ(c0, c0, 0, didr);
+  return (didr >> 16) & 0xf;
+}
+
+/* Check if 8-bit byte-address select is available.
+ * This clobbers WRP 0.
+ */
+
+static uint8_t get_max_wp_len(void)
+{
+  struct arch_hw_breakpoint_ctrl ctrl;
+  uint32_t ctrl_reg;
+  uint8_t size = 4;
+
+  if (get_debug_arch() < ARM_DEBUG_ARCH_V7_ECP14)
+    {
+      goto out;
+    }
+
+  memset(&ctrl, 0, sizeof(ctrl));
+  ctrl.len = ARM_BREAKPOINT_LEN_8;
+  ctrl_reg = encode_ctrl_reg(&ctrl);
+
+  write_wb_reg(ARM_BASE_WVR, 0);
+  write_wb_reg(ARM_BASE_WCR, ctrl_reg);
+  if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg)
+    {
+      size = 8;
+    }
+
+out:
+  return size;
+}
+
+/* Determine architecture is supported */
+
+static int debug_arch_supported(void)
+{
+  uint8_t arch = get_debug_arch();
+
+  /* We don't support the memory-mapped interface. */
+
+  return (arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14) ||

Review Comment:
   So can i consider moving this file to the common folder? Because hwdebug in 
the Linux kernel is a common implementation, by judging the arch



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to