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/nuttx.git

commit 1df6aa92f9da4930e651658b17b068c44e3a0da2
Author: wangmingrong1 <wangmingro...@xiaomi.com>
AuthorDate: Tue Jun 24 16:59:32 2025 +0800

    arm64: Support hardware debug
    
    Signed-off-by: wangmingrong1 <wangmingro...@xiaomi.com>
---
 arch/arm64/Kconfig                       |   1 +
 arch/arm64/src/common/CMakeLists.txt     |   4 +
 arch/arm64/src/common/Make.defs          |   4 +
 arch/arm64/src/common/arm64_hwdebug.c    | 460 +++++++++++++++++++++++++++++++
 arch/arm64/src/common/arm64_hwdebug.h    | 124 +++++++++
 arch/arm64/src/common/arm64_initialize.c |   4 +
 arch/arm64/src/common/arm64_internal.h   |   4 +
 7 files changed, 601 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f3fb57f077..016809c4e0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -343,6 +343,7 @@ config ARCH_CPU_UNKNOWN
        default n
        select ARCH_ARMV8A
        select ARCH_HAVE_TRUSTZONE
+       select ARCH_HAVE_DEBUG
        select ARCH_DCACHE
        select ARCH_ICACHE
        select ARCH_HAVE_MMU
diff --git a/arch/arm64/src/common/CMakeLists.txt 
b/arch/arm64/src/common/CMakeLists.txt
index e704078ed4..4a8c826755 100644
--- a/arch/arm64/src/common/CMakeLists.txt
+++ b/arch/arm64/src/common/CMakeLists.txt
@@ -59,6 +59,10 @@ if(CONFIG_ARM64_GIC_VERSION EQUAL 2)
   endif()
 endif()
 
+if(CONFIG_ARCH_HAVE_DEBUG)
+  list(APPEND SRCS arm64_hwdebug.c)
+endif()
+
 if(CONFIG_ARCH_HAVE_EL3)
   list(APPEND SRCS arm64_smccc.S)
 endif()
diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs
index 3c1dacb3d0..8a6328af1e 100644
--- a/arch/arm64/src/common/Make.defs
+++ b/arch/arm64/src/common/Make.defs
@@ -67,6 +67,10 @@ CMN_CSRCS += arm64_gicv2m.c
 endif
 endif
 
+ifneq ($(CONFIG_ARCH_HAVE_DEBUG),)
+CMN_CSRCS += arm64_hwdebug.c
+endif
+
 ifeq ($(CONFIG_ARCH_HAVE_EL3),y)
 CMN_ASRCS += arm64_smccc.S
 endif
diff --git a/arch/arm64/src/common/arm64_hwdebug.c 
b/arch/arm64/src/common/arm64_hwdebug.c
new file mode 100644
index 0000000000..9343776a0b
--- /dev/null
+++ b/arch/arm64/src/common/arm64_hwdebug.c
@@ -0,0 +1,460 @@
+/****************************************************************************
+ * arch/arm64/src/common/arm64_hwdebug.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 <nuttx/mm/kasan.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "arm64_fatal.h"
+#include "arm64_hwdebug.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ARM64_DBGBWCR_VAL(type, len) \
+  (arm64_convert_type(type) | arm64_convert_size(len) | \
+   ARM64_DBGBCR_PAC_ALL | ARM64_DBGBWCR_E)
+
+#define ARM64_MASK_ADDR(addr) \
+  ((uint64_t)kasan_clear_tag((void *)addr) & ~0x3)
+
+/****************************************************************************
+ * Private Type
+ ****************************************************************************/
+
+struct arm64_debugpoint_s
+{
+  int type;
+  void *addr;
+  size_t size;
+  debug_callback_t callback;
+  void *arg;
+};
+
+struct arm64_debug_s
+{
+  /* Breakpoint currently in use for each BRP, WRP */
+
+  struct arm64_debugpoint_s brps[ID_AA64DFR0_MAX_BRPS];
+  struct arm64_debugpoint_s wrps[ID_AA64DFR0_MAX_WRPS];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct arm64_debug_s g_arm64_debug[CONFIG_SMP_NCPUS];
+
+/****************************************************************************
+ * Private Function
+ ****************************************************************************/
+
+static uint32_t arm64_convert_type(int type)
+{
+  switch (type)
+    {
+      case DEBUGPOINT_WATCHPOINT_RO:
+        return ARM64_DBGBWCR_LSC_LOAD << ARM64_DBGBWCR_LSC_OFFSET;
+
+      case DEBUGPOINT_WATCHPOINT_WO:
+        return ARM64_DBGBWCR_LSC_STORE << ARM64_DBGBWCR_LSC_OFFSET;
+
+      case DEBUGPOINT_WATCHPOINT_RW:
+        return (ARM64_DBGBWCR_LSC_LOAD | ARM64_DBGBWCR_LSC_STORE)
+               << ARM64_DBGBWCR_LSC_OFFSET;
+
+      case DEBUGPOINT_BREAKPOINT:
+      case DEBUGPOINT_STEPPOINT:
+      default:
+        return ARM64_DBGBWCR_LSC_EXECUTE << ARM64_DBGBWCR_LSC_OFFSET;
+    }
+}
+
+static uint32_t arm64_convert_size(size_t len)
+{
+  switch (len)
+    {
+      case 1:
+        return ARM64_DBGBWCR_BAS_LEN_1 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 2:
+        return ARM64_DBGBWCR_BAS_LEN_2 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 3:
+        return ARM64_DBGBWCR_BAS_LEN_3 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 4:
+        return ARM64_DBGBWCR_BAS_LEN_4 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 5:
+        return ARM64_DBGBWCR_BAS_LEN_5 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 6:
+        return ARM64_DBGBWCR_BAS_LEN_6 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 7:
+        return ARM64_DBGBWCR_BAS_LEN_7 << ARM64_DBGBWCR_BAS_OFFSET;
+      case 8:
+      default:
+        return ARM64_DBGBWCR_BAS_LEN_8 << ARM64_DBGBWCR_BAS_OFFSET;
+    }
+}
+
+/* Determine number of usable WRPs available. */
+
+static int arm64_get_num_wrps(void)
+{
+  return (read_sysreg(id_aa64dfr0_el1) >> ID_AA64DFR0_EL1_WRPS_OFFSET)
+         & ID_AA64DFR0_EL1_WRPS_MASK;
+}
+
+/* Determine number of usable BRPs available. */
+
+static int arm64_get_num_brps(void)
+{
+  return (read_sysreg(id_aa64dfr0_el1) >> ID_AA64DFR0_EL1_BRPS_OFFSET)
+         & ID_AA64DFR0_EL1_BRPS_MASK;
+}
+
+/****************************************************************************
+ * Name: arm64_watchpoint_add
+ *
+ * Description:
+ *   Add a watchpoint on the address.
+ *
+ * Input Parameters:
+ *  type - The type of the watchpoint
+ *  addr - The address to be watched
+ *  size - The size of the address to be watched
+ *
+ * Returned Value:
+ *  Index in wprs array on success; a negated errno value on failure
+ *
+ * Notes:
+ *  The size of the watchpoint is determined by the hardware.
+ *
+ ****************************************************************************/
+
+static int arm64_watchpoint_add(int type, uint64_t addr, size_t size)
+{
+  int num = arm64_get_num_wrps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (!(ARM64_DBG_GETN(wcr, i) & ARM64_DBGBWCR_E))
+        {
+          ARM64_DBG_SETN(wvr, i, ARM64_MASK_ADDR(addr));
+          ARM64_DBG_SETN(wcr, i, ARM64_DBGBWCR_VAL(type, size));
+          return i;
+        }
+    }
+
+  return -ENOSPC;
+}
+
+/****************************************************************************
+ * Name: arm64_watchpoint_remove
+ *
+ * Description:
+ *   Remove a watchpoint on the address.
+ *
+ * Input Parameters:
+ *   addr - The address to be watched.
+ *
+ * Returned Value:
+ *  Index in wprs array on success; a negated errno value on failure
+ *
+ ****************************************************************************/
+
+static int arm64_watchpoint_remove(uint64_t addr)
+{
+  int num = arm64_get_num_wrps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (ARM64_DBG_GETN(wvr, i) == ARM64_MASK_ADDR(addr))
+        {
+          ARM64_DBG_SETN(wcr, i, 0);
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+/****************************************************************************
+ * Name: arm64_breakpoint_add
+ *
+ * Description:
+ *   Add a breakpoint on addr.
+ *
+ * Input Parameters:
+ *  addr - The address to break.
+ *
+ * Returned Value:
+ *  Index in bprs array on success; a negated errno value on failure
+ *
+ * Notes:
+ *  1. If breakpoint is already set, it will do nothing.
+ *  2. If all comparators are in use, it will return -1.
+ *  3. When the breakpoint trigger, if enable monitor exception already ,
+ *     will cause a debug monitor exception, oaddr=0x4020392ctherwise will
+ *     cause a hard fault.
+ *
+ ****************************************************************************/
+
+static int arm64_breakpoint_add(uintptr_t addr)
+{
+  int num = arm64_get_num_brps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (!(ARM64_DBG_GETN(bcr, i) & ARM64_DBGBWCR_E))
+        {
+          ARM64_DBG_SETN(bvr, i, ARM64_MASK_ADDR(addr));
+          ARM64_DBG_SETN(bcr, i,
+                         ARM64_DBGBWCR_VAL(DEBUGPOINT_BREAKPOINT, 8));
+          return i;
+        }
+    }
+
+  return -ENOSPC;
+}
+
+/****************************************************************************
+ * Name: arm64_breakpoint_remove
+ *
+ * Description:
+ *   Remove a breakpoint on addr.
+ *
+ * Input Parameters:
+ *  addr - The address to remove.
+ *
+ * Returned Value:
+ *  Index in bprs array on success; a negated errno value on failure
+ *
+ ****************************************************************************/
+
+static int arm64_breakpoint_remove(uintptr_t addr)
+{
+  int num = arm64_get_num_brps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (ARM64_DBG_GETN(bvr, i) == ARM64_MASK_ADDR(addr))
+        {
+          ARM64_DBG_SETN(bcr, i, 0);
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int arm64_watchpoint_match(uint64_t *regs, uint64_t far, uint64_t esr)
+{
+  struct arm64_debugpoint_s *dp = g_arm64_debug[this_cpu()].wrps;
+  int num = arm64_get_num_wrps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (ARM64_MASK_ADDR(dp[i].addr) == ARM64_MASK_ADDR(far))
+        {
+          dp[i].callback(dp[i].type, dp[i].addr,
+                         dp[i].size, dp[i].arg);
+          return OK;
+        }
+    }
+
+  return EFAULT;
+}
+
+static int arm64_breakpoint_match(uint64_t *regs, uint64_t far, uint64_t esr)
+{
+  struct arm64_debugpoint_s *dp = g_arm64_debug[this_cpu()].brps;
+  int num = arm64_get_num_brps();
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      if (ARM64_MASK_ADDR(dp[i].addr) == ARM64_MASK_ADDR(up_getusrpc(regs)))
+        {
+          dp[i].callback(dp[i].type, dp[i].addr,
+                         dp[i].size, dp[i].arg);
+          return OK;
+        }
+    }
+
+  return EFAULT;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm64_enable_dbgmonitor
+ *
+ * Description:
+ *   This function enables the debug monitor exception.
+ *
+ ****************************************************************************/
+
+int arm64_enable_dbgmonitor(void)
+{
+  uint32_t mdscr;
+
+  /* Determine how many BRPs/WRPs are available.
+   * And work out the maximum supported watchpoint length.
+   */
+
+  binfo("found %d breakpoint and %d watchpoint registers.\n",
+        arm64_get_num_brps(), arm64_get_num_wrps());
+
+  mdscr = read_sysreg(mdscr_el1);
+  mdscr |= ARM64_MDSCR_EL1_MDE | ARM64_MDSCR_EL1_KDE;
+  write_sysreg(mdscr, mdscr_el1);
+
+  arm64_register_debug_hook(DBG_ESR_EVT_HWBP, arm64_breakpoint_match);
+  arm64_register_debug_hook(DBG_ESR_EVT_HWWP, arm64_watchpoint_match);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ *
+ * Description:
+ *   Add a debugpoint.
+ *
+ * Input Parameters:
+ *   type     - The debugpoint type. optional value:
+ *              DEBUGPOINT_WATCHPOINT_RO - Read only watchpoint.
+ *              DEBUGPOINT_WATCHPOINT_WO - Write only watchpoint.
+ *              DEBUGPOINT_WATCHPOINT_RW - Read and write watchpoint.
+ *              DEBUGPOINT_BREAKPOINT    - Breakpoint.
+ *              DEBUGPOINT_STEPPOINT     - Single step.
+ *   addr     - The address to be debugged.
+ *   size     - The watchpoint size. only for watchpoint.
+ *   callback - The callback function when debugpoint triggered.
+ *              if NULL, the debugpoint will be removed.
+ *   arg      - The argument of callback function.
+ *
+ * Returned Value:
+ *  Zero on success; a negated errno value on failure
+ *
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, void *addr, size_t size,
+                      debug_callback_t callback, void *arg)
+{
+  struct arm64_debugpoint_s *dp;
+  int cpu = this_cpu();
+  int ret = -EINVAL;
+
+  if (type == DEBUGPOINT_BREAKPOINT)
+    {
+      ret = arm64_breakpoint_add((uintptr_t)addr);
+      dp = g_arm64_debug[cpu].brps;
+    }
+  else if (type == DEBUGPOINT_WATCHPOINT_RO ||
+           type == DEBUGPOINT_WATCHPOINT_WO ||
+           type == DEBUGPOINT_WATCHPOINT_RW)
+    {
+      ret = arm64_watchpoint_add(type, (uintptr_t)addr, size);
+      dp = g_arm64_debug[cpu].wrps;
+    }
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  dp[ret].type = type;
+  dp[ret].addr = addr;
+  dp[ret].size = size;
+  dp[ret].callback = callback;
+  dp[ret].arg = arg;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_remove
+ *
+ * Description:
+ *   Remove a debugpoint.
+ *
+ * Input Parameters:
+ *   type     - The debugpoint type. optional value:
+ *              DEBUGPOINT_WATCHPOINT_RO - Read only watchpoint.
+ *              DEBUGPOINT_WATCHPOINT_WO - Write only watchpoint.
+ *              DEBUGPOINT_WATCHPOINT_RW - Read and write watchpoint.
+ *              DEBUGPOINT_BREAKPOINT    - Breakpoint.
+ *              DEBUGPOINT_STEPPOINT     - Single step.
+ *   addr     - The address to be debugged.
+ *   size     - The watchpoint size. only for watchpoint.
+ *
+ * Returned Value:
+ *  Zero on success; a negated errno value on failure
+ *
+ ****************************************************************************/
+
+int up_debugpoint_remove(int type, void *addr, size_t size)
+{
+  struct arm64_debugpoint_s *dp;
+  int cpu = this_cpu();
+  int ret = -EINVAL;
+
+  if (type == DEBUGPOINT_BREAKPOINT)
+    {
+      ret = arm64_breakpoint_remove((uintptr_t)addr);
+      dp = g_arm64_debug[cpu].brps;
+    }
+  else if (type == DEBUGPOINT_WATCHPOINT_RO ||
+           type == DEBUGPOINT_WATCHPOINT_WO ||
+           type == DEBUGPOINT_WATCHPOINT_RW)
+    {
+      ret = arm64_watchpoint_remove((uintptr_t)addr);
+      dp = g_arm64_debug[cpu].wrps;
+    }
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  dp[ret].type = 0;
+  dp[ret].addr = 0;
+  dp[ret].size = 0;
+  dp[ret].callback = NULL;
+  dp[ret].arg = NULL;
+
+  return OK;
+}
diff --git a/arch/arm64/src/common/arm64_hwdebug.h 
b/arch/arm64/src/common/arm64_hwdebug.h
new file mode 100644
index 0000000000..0efabee14e
--- /dev/null
+++ b/arch/arm64/src/common/arm64_hwdebug.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+ * arch/arm64/src/common/arm64_hwdebug.h
+ *
+ * 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.
+ *
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_COMMON_ARM64_HWDEBUG_H
+#define __ARCH_ARM64_SRC_COMMON_ARM64_HWDEBUG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/bits.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ARM64_DBGBWCR_E                   BIT(0)
+
+#define ARM64_DBGBWCR_LSC_OFFSET          3
+#define ARM64_DBGBWCR_LSC_EXECUTE         0
+#define ARM64_DBGBWCR_LSC_LOAD            1
+#define ARM64_DBGBWCR_LSC_STORE           2
+
+#define ARM64_DBGBWCR_BAS_OFFSET          5
+#define ARM64_DBGBWCR_BAS_LEN_1           0x1
+#define ARM64_DBGBWCR_BAS_LEN_2           0x3
+#define ARM64_DBGBWCR_BAS_LEN_3           0x7
+#define ARM64_DBGBWCR_BAS_LEN_4           0xf
+#define ARM64_DBGBWCR_BAS_LEN_5           0x1f
+#define ARM64_DBGBWCR_BAS_LEN_6           0x3f
+#define ARM64_DBGBWCR_BAS_LEN_7           0x7f
+#define ARM64_DBGBWCR_BAS_LEN_8           0xff
+
+#define ARM64_DBGBCR_PAC_PRIV             BIT(1)
+#define ARM64_DBGBCR_PAC_USER             BIT(2)
+#define ARM64_DBGBCR_PAC_ALL              (ARM64_DBGBCR_PAC_PRIV | 
ARM64_DBGBCR_PAC_USER)
+
+#define ARM64_MDSCR_EL1_KDE               BIT(13)
+#define ARM64_MDSCR_EL1_MDE               BIT(15)
+
+#define ID_AA64DFR0_EL1_BRPS_MASK         0xf
+#define ID_AA64DFR0_EL1_BRPS_OFFSET       12
+
+#define ID_AA64DFR0_EL1_WRPS_MASK         0xf
+#define ID_AA64DFR0_EL1_WRPS_OFFSET       20
+
+#define ID_AA64DFR0_MAX_BRPS              16
+#define ID_AA64DFR0_MAX_WRPS              16
+
+#define ARM64_DBG_SET_CASE(reg, n, val)   \
+  case n:                                 \
+    write_sysreg(val, dbg##reg##n##_el1); \
+    break;
+
+#define ARM64_DBG_GET_CASE(reg, n, val)   \
+  case n:                                 \
+    val = read_sysreg(dbg##reg##n##_el1); \
+    break;
+
+#define ARM64_DBG_SETN(reg, n, val)       \
+  switch (n)                              \
+    {                                     \
+      ARM64_DBG_SET_CASE(reg, 0, val)     \
+      ARM64_DBG_SET_CASE(reg, 1, val)     \
+      ARM64_DBG_SET_CASE(reg, 2, val)     \
+      ARM64_DBG_SET_CASE(reg, 3, val)     \
+      ARM64_DBG_SET_CASE(reg, 4, val)     \
+      ARM64_DBG_SET_CASE(reg, 5, val)     \
+      ARM64_DBG_SET_CASE(reg, 6, val)     \
+      ARM64_DBG_SET_CASE(reg, 7, val)     \
+      ARM64_DBG_SET_CASE(reg, 8, val)     \
+      ARM64_DBG_SET_CASE(reg, 9, val)     \
+      ARM64_DBG_SET_CASE(reg, 10, val)    \
+      ARM64_DBG_SET_CASE(reg, 11, val)    \
+      ARM64_DBG_SET_CASE(reg, 12, val)    \
+      ARM64_DBG_SET_CASE(reg, 13, val)    \
+      ARM64_DBG_SET_CASE(reg, 14, val)    \
+      ARM64_DBG_SET_CASE(reg, 15, val)    \
+    }
+
+#define ARM64_DBG_GETN(reg, n)            \
+  ({                                      \
+    uint64_t _val = 0;                    \
+    switch (n)                            \
+      {                                   \
+        ARM64_DBG_GET_CASE(reg, 0, _val)  \
+        ARM64_DBG_GET_CASE(reg, 1, _val)  \
+        ARM64_DBG_GET_CASE(reg, 2, _val)  \
+        ARM64_DBG_GET_CASE(reg, 3, _val)  \
+        ARM64_DBG_GET_CASE(reg, 4, _val)  \
+        ARM64_DBG_GET_CASE(reg, 5, _val)  \
+        ARM64_DBG_GET_CASE(reg, 6, _val)  \
+        ARM64_DBG_GET_CASE(reg, 7, _val)  \
+        ARM64_DBG_GET_CASE(reg, 8, _val)  \
+        ARM64_DBG_GET_CASE(reg, 9, _val)  \
+        ARM64_DBG_GET_CASE(reg, 10, _val) \
+        ARM64_DBG_GET_CASE(reg, 11, _val) \
+        ARM64_DBG_GET_CASE(reg, 12, _val) \
+        ARM64_DBG_GET_CASE(reg, 13, _val) \
+        ARM64_DBG_GET_CASE(reg, 14, _val) \
+        ARM64_DBG_GET_CASE(reg, 15, _val) \
+      }                                   \
+    _val;                                 \
+  })
+
+#endif  /* __ARCH_ARM64_SRC_COMMON_ARM64_HWDEBUG_H */
\ No newline at end of file
diff --git a/arch/arm64/src/common/arm64_initialize.c 
b/arch/arm64/src/common/arm64_initialize.c
index 49388ad6cb..9354e2a30c 100644
--- a/arch/arm64/src/common/arm64_initialize.c
+++ b/arch/arm64/src/common/arm64_initialize.c
@@ -217,5 +217,9 @@ void up_initialize(void)
   arm64_fpu_procfs_register();
 #endif
 
+#ifdef CONFIG_ARCH_HAVE_DEBUG
+  arm64_enable_dbgmonitor();
+#endif
+
 #endif
 }
diff --git a/arch/arm64/src/common/arm64_internal.h 
b/arch/arm64/src/common/arm64_internal.h
index 7ac7fb09ab..4d5e38d9f6 100644
--- a/arch/arm64/src/common/arm64_internal.h
+++ b/arch/arm64/src/common/arm64_internal.h
@@ -393,6 +393,10 @@ size_t arm64_stack_check(void *stackbase, size_t nbytes);
 void arm64_stack_color(void *stackbase, size_t nbytes);
 #endif
 
+#ifdef CONFIG_ARCH_HAVE_DEBUG
+void arm64_enable_dbgmonitor(void);
+#endif
+
 #undef EXTERN
 #ifdef __cplusplus
 }

Reply via email to