xiaoxiang781216 commented on code in PR #12554:
URL: https://github.com/apache/nuttx/pull/12554#discussion_r1667389700


##########
arch/risc-v/include/qemu-rv/chip.h:
##########
@@ -21,4 +21,14 @@
 #ifndef __ARCH_RISCV_INCLUDE_QEMU_RV_CHIP_H
 #define __ARCH_RISCV_INCLUDE_QEMU_RV_CHIP_H
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Refer to https://github.com/qemu/qemu/blob/master/target/riscv/debug.c
+ * for the definition of the following macros.
+ */
+
+#define RISCV_DEBUG_NR_TRIGGER 2

Review Comment:
   why not detect the trigger number through `tselect`?



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)
+        {
+          mc.match = 1;
+
+          addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                        ((size - 1) >> 1);
+
+          WRITE_CSR(CSR_TDATA2, addr_napot);
+        }
+      else
+        {
+          mc.match = 0;
+          WRITE_CSR(CSR_TDATA2, (uintptr_t)addr);
+        }
+
+      WRITE_CSR(CSR_TDATA1, mc.reg);
+
+      /* Register the callback and arg */
+
+      g_trigger_map[slot].type     = type;
+      g_trigger_map[slot].address  = addr;
+      g_trigger_map[slot].size     = size;
+      g_trigger_map[slot].callback = callback;
+      g_trigger_map[slot].arg      = arg;
+
+      /* Special handling for QEMU since it does not implement
+       * the TCONTROL register, verified on QEMU 9.0.1.
+       */
+
+#ifndef CONFIG_ARCH_CHIP_QEMU_RV
+      /* Enable trigger in M-mode */
+
+      WRITE_CSR(CSR_TCONTROL, TCONTROL_MTE);
+#endif
+    }
+  else
+    {
+      ret = -ENOSPC;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_remove
+ ****************************************************************************/
+
+int up_debugpoint_remove(int type, FAR void *addr, size_t size)

Review Comment:
   remove FAR from the whole file



##########
arch/risc-v/src/common/Make.defs:
##########
@@ -50,6 +50,10 @@ ifeq ($(CONFIG_RISCV_MISALIGNED_HANDLER),y)
 CMN_CSRCS += riscv_misaligned.c
 endif
 
+ifeq ($(CONFIG_ARCH_HAVE_DEBUG),y)
+  CMN_CSRCS += riscv_debug.c

Review Comment:
   remove the indent like other line



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;

Review Comment:
   ```suggestion
             return i;
   ```
   and remove slot



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add

Review Comment:
   ```suggestion
    * Name: riscv_debug_init
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */

Review Comment:
   let's move to csr.h



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)

Review Comment:
   ```suggestion
   static int riscv_debug_find_slot(int type, void *address, size_t size)
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)

Review Comment:
   ```suggestion
   static int riscv_debug_handler(int irq, void *context, void *arg)
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,

Review Comment:
   ```suggestion
                                      g_trigger_map[slot].address,
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;

Review Comment:
   ```suggestion
     return -ENOENT;
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));

Review Comment:
   remove, don't need



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)

Review Comment:
   ```suggestion
     if (slot < 0)
       {
         return slot;
       }
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;

Review Comment:
   ```suggestion
             return -EINVAL;
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)
+        {
+          mc.match = 1;
+
+          addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                        ((size - 1) >> 1);
+
+          WRITE_CSR(CSR_TDATA2, addr_napot);
+        }
+      else
+        {
+          mc.match = 0;
+          WRITE_CSR(CSR_TDATA2, (uintptr_t)addr);
+        }
+
+      WRITE_CSR(CSR_TDATA1, mc.reg);
+
+      /* Register the callback and arg */
+
+      g_trigger_map[slot].type     = type;
+      g_trigger_map[slot].address  = addr;
+      g_trigger_map[slot].size     = size;
+      g_trigger_map[slot].callback = callback;
+      g_trigger_map[slot].arg      = arg;
+
+      /* Special handling for QEMU since it does not implement
+       * the TCONTROL register, verified on QEMU 9.0.1.
+       */
+
+#ifndef CONFIG_ARCH_CHIP_QEMU_RV
+      /* Enable trigger in M-mode */
+
+      WRITE_CSR(CSR_TCONTROL, TCONTROL_MTE);
+#endif
+    }
+  else
+    {
+      ret = -ENOSPC;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_remove
+ ****************************************************************************/
+
+int up_debugpoint_remove(int type, FAR void *addr, size_t size)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+
+  /* Find the existing debugpoint */
+
+  slot = debug_find_slot(type, addr, size);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);

Review Comment:
   let's set CSR_TDATA1 to zero directly



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)
+        {
+          mc.match = 1;
+
+          addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                        ((size - 1) >> 1);
+
+          WRITE_CSR(CSR_TDATA2, addr_napot);
+        }
+      else
+        {
+          mc.match = 0;
+          WRITE_CSR(CSR_TDATA2, (uintptr_t)addr);
+        }
+
+      WRITE_CSR(CSR_TDATA1, mc.reg);
+
+      /* Register the callback and arg */
+
+      g_trigger_map[slot].type     = type;
+      g_trigger_map[slot].address  = addr;
+      g_trigger_map[slot].size     = size;
+      g_trigger_map[slot].callback = callback;
+      g_trigger_map[slot].arg      = arg;
+
+      /* Special handling for QEMU since it does not implement
+       * the TCONTROL register, verified on QEMU 9.0.1.
+       */
+
+#ifndef CONFIG_ARCH_CHIP_QEMU_RV
+      /* Enable trigger in M-mode */
+
+      WRITE_CSR(CSR_TCONTROL, TCONTROL_MTE);
+#endif
+    }
+  else
+    {
+      ret = -ENOSPC;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_remove
+ ****************************************************************************/
+
+int up_debugpoint_remove(int type, FAR void *addr, size_t size)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+
+  /* Find the existing debugpoint */
+
+  slot = debug_find_slot(type, addr, size);
+
+  if (slot >= 0)

Review Comment:
   ```suggestion
     if (slot < 0)
       {
         return slot;
       }
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)
+        {
+          mc.match = 1;
+
+          addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                        ((size - 1) >> 1);
+
+          WRITE_CSR(CSR_TDATA2, addr_napot);
+        }
+      else
+        {
+          mc.match = 0;
+          WRITE_CSR(CSR_TDATA2, (uintptr_t)addr);
+        }
+
+      WRITE_CSR(CSR_TDATA1, mc.reg);
+
+      /* Register the callback and arg */
+
+      g_trigger_map[slot].type     = type;
+      g_trigger_map[slot].address  = addr;
+      g_trigger_map[slot].size     = size;
+      g_trigger_map[slot].callback = callback;
+      g_trigger_map[slot].arg      = arg;
+
+      /* Special handling for QEMU since it does not implement
+       * the TCONTROL register, verified on QEMU 9.0.1.
+       */
+
+#ifndef CONFIG_ARCH_CHIP_QEMU_RV

Review Comment:
   why check CONFIG_ARCH_CHIP_QEMU_RV in common code



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)
+        {
+          mc.match = 1;
+
+          addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                        ((size - 1) >> 1);
+
+          WRITE_CSR(CSR_TDATA2, addr_napot);
+        }
+      else
+        {
+          mc.match = 0;

Review Comment:
   let's add macro for each possible match



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;

Review Comment:
   let's add macro for each possible action



##########
arch/risc-v/src/common/riscv_exception.c:
##########
@@ -311,4 +311,13 @@ void riscv_exception_attach(void)
 #else
   irq_attach(RISCV_IRQ_MSOFT, riscv_exception, NULL);
 #endif
+
+  /* Attach the breakpoint interrupt handler,
+   * only if the LIB_GDBSTUB is enabled the
+   * debug infrastructure is used acutally.
+   */
+
+#if defined(CONFIG_ARCH_HAVE_DEBUG) && defined(CONFIG_LIB_GDBSTUB)
+  riscv_debug_init();

Review Comment:
   let's call riscv_debug_init when up_debugpoint_add get called first time



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else

Review Comment:
   why not handle DEBUGPOINT_STEPPOINT



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,381 @@
+/****************************************************************************
+ * arch/risc-v/src/common/riscv_debug.c
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Notice:
+ *
+ * This driver is based on the RISC-V Debug Specification, version 0.13.2.
+ * The latest version of the specification can be found at:
+ * https://github.com/riscv/riscv-debug-spec
+ *
+ * The 1.0 version of the specification is still in RC phase, so there are
+ * no chips that support it yet. The 0.13.2 version is the latest stable
+ * version and some chips support it (e.g. QEMU RV, ESP32C3, BL602 etc).
+ *
+ * So this driver may needs to be updated when there is a new chip that
+ * supports the 1.0 version of the specification.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/chip/chip.h>
+#include <arch/csr.h>
+
+#include <stdbool.h>
+
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Check the essential definition that must from chip vendor */
+
+#ifndef RISCV_DEBUG_NR_TRIGGER
+#  error "Number of trigger in debug module is missing"
+#endif
+
+/* CSR bits for TCONTROL */
+
+#define TCONTROL_MTE  (1 << 3) /* M-mode trigger enable */
+#define TCONTROL_MPTE (1 << 7) /* M-mode previous trigger enable */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Trigger Match Control, from version 0.13.2.
+ * Read https://riscv.org/wp-content/uploads/2019/03/riscv-debug-release.pdf
+ * for more information
+ */
+
+union mcontrol
+{
+  uintptr_t reg;
+  struct
+    {
+      uintptr_t load : 1;
+      uintptr_t store : 1;
+      uintptr_t execute : 1;
+      uintptr_t u : 1;
+      uintptr_t s : 1;
+      uintptr_t reserved0 : 1;
+      uintptr_t m : 1;
+      uintptr_t match : 4;
+      uintptr_t chain : 1;
+      uintptr_t action : 4;
+      uintptr_t sizelo : 2;
+      uintptr_t timing : 1;
+      uintptr_t select : 1;
+      uintptr_t hit : 1;
+#ifdef CONFIG_ARCH_RV64
+      uintptr_t sizehi : 2;
+      uintptr_t reserved1 : 30;
+#endif
+      uintptr_t maskmax : 6;
+      uintptr_t dmode : 1;
+      uintptr_t type : 4;
+    };
+};
+
+struct riscv_debug_trigger
+{
+  int type;                  /* Trigger type */
+  void *address;             /* Trigger address */
+  size_t size;               /* Trigger region size */
+  debug_callback_t callback; /* Debug callback */
+  void *arg;                 /* Debug callback argument */
+};
+
+/* Save the trigger address info */
+
+static struct riscv_debug_trigger g_trigger_map[RISCV_DEBUG_NR_TRIGGER];
+static bool g_support_napot = false;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: debug_find_slot
+ *
+ * Description:
+ *   -1 on fail, if address is NULL then to find a free slot in trigger map
+ *
+ ****************************************************************************/
+
+static int debug_find_slot(int type, void *address, size_t size)
+{
+  int slot = -1;
+  int i;
+
+  for (i = 0; i < RISCV_DEBUG_NR_TRIGGER; i++)
+    {
+      if (g_trigger_map[i].type == type &&
+          g_trigger_map[i].address == address &&
+          g_trigger_map[i].size == size)
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  return slot;
+}
+
+static int riscv_debug_handler(int irq, FAR void *context, FAR void *arg)
+{
+  /* Get the trigger index */
+
+  int slot = READ_CSR(CSR_TSELECT);
+
+  DEBUGASSERT(slot >= 0);
+  DEBUGASSERT(slot < RISCV_DEBUG_NR_TRIGGER);
+
+  /* Call the trigger callback */
+
+  if (g_trigger_map[slot].callback)
+    {
+      g_trigger_map[slot].callback(g_trigger_map[slot].type,
+                                  g_trigger_map[slot].address,
+                                  g_trigger_map[slot].size,
+                                  g_trigger_map[slot].arg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Clear the global trigger info & mark them as free slots */
+
+  memset(g_trigger_map, 0, sizeof(g_trigger_map));
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  mc.match = 1;
+
+  /* Write it to tdata1 and read back
+   * to check if the NAPOT is supported
+   */
+
+  WRITE_CSR(CSR_TDATA1, mc.reg);
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  if (mc.match == 1)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, FAR void *addr, size_t size,
+                      debug_callback_t callback, FAR void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+
+  /* Find a free slot */
+
+  slot = debug_find_slot(0, 0, 0);
+
+  if (slot >= 0)
+    {
+      /* Select the trigger */
+
+      WRITE_CSR(CSR_TSELECT, slot);
+
+      /* Fetch the current setting from tdata1 */
+
+      mc.reg = READ_CSR(CSR_TDATA1);
+
+      /* Configure trigger */
+
+      mc.m = 1;
+      mc.u = 1;
+      mc.hit = 0;
+      mc.dmode = 0;
+      mc.action = 0;
+
+      mc.execute = 0;
+      mc.load = 0;
+      mc.store = 0;
+
+      if (type == DEBUGPOINT_BREAKPOINT)
+        {
+          mc.execute = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RO)
+        {
+          mc.load = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_WO)
+        {
+          mc.store = 1;
+        }
+      else if (type == DEBUGPOINT_WATCHPOINT_RW)
+        {
+          mc.load = 1;
+          mc.store = 1;
+        }
+      else
+        {
+          ret = -EINVAL;
+          return ret;
+        }
+
+      /* From RISC-V Debug Specification:
+       * tdata1(mcontrol) match = 0 : Exact byte match
+       *
+       * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two):
+       *
+       * Examples for understanding how to calculate match pattern to tdata2:
+       *
+       * nnnn...nnnnn 1-byte  Exact byte match
+       * nnnn...nnnn0 2-byte  NAPOT range
+       * nnnn...nnn01 4-byte  NAPOT range
+       * nnnn...nn011 8-byte  NAPOT range
+       * nnnn...n0111 16-byte NAPOT range
+       * nnnn...01111 32-byte NAPOT range
+       * ...
+       * n011...11111 2^31 byte NAPOT range
+       *  * where n are bits from original address
+       */
+
+      if (size > 1 && g_support_napot)

Review Comment:
   why not use sizelo/sizehi



##########
arch/risc-v/src/common/riscv_internal.h:
##########
@@ -390,6 +390,10 @@ void riscv_cpu_boot(int cpu);
 int riscv_pause_handler(int irq, void *c, void *arg);
 #endif
 
+#ifdef CONFIG_ARCH_HAVE_DEBUG
+void riscv_debug_init(void);

Review Comment:
   remove



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to