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


##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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

Review Comment:
   ```suggestion
    * Name: riscv_debug_find_slot
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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;

Review Comment:
   ```suggestion
     return 0;
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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: riscv_debug_init
+ ****************************************************************************/
+
+void riscv_debug_init(void)

Review Comment:
   ```suggestion
   static void riscv_debug_init(void)
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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: riscv_debug_init
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  /* REVISIT: NAPOT match is supported and tested on
+   * QEMU and ESP32C3, prefer to use it.
+   */
+
+  mc.match = MATCH_TYPE_TOPBITS;
+
+  /* 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 == MATCH_TYPE_TOPBITS)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, void *addr, size_t size,
+                      debug_callback_t callback, void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+  static bool g_debug_initiliazed = false;

Review Comment:
   move to line 135



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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: riscv_debug_init
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  /* REVISIT: NAPOT match is supported and tested on
+   * QEMU and ESP32C3, prefer to use it.
+   */
+
+  mc.match = MATCH_TYPE_TOPBITS;
+
+  /* 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 == MATCH_TYPE_TOPBITS)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, void *addr, size_t size,
+                      debug_callback_t callback, void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+  static bool g_debug_initiliazed = false;
+
+  if (g_debug_initiliazed == false)
+    {
+      riscv_debug_init();
+      g_debug_initiliazed = true;
+    }
+
+  /* Find a free slot */
+
+  slot = riscv_debug_find_slot(0, 0, 0);
+

Review Comment:
   remove



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * Private Data

Review Comment:
   ```suggestion
    * Private Type
   ```



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 */
+};
+

Review Comment:
   add Private Data section



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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: riscv_debug_init
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  /* REVISIT: NAPOT match is supported and tested on
+   * QEMU and ESP32C3, prefer to use it.
+   */
+
+  mc.match = MATCH_TYPE_TOPBITS;
+
+  /* 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 == MATCH_TYPE_TOPBITS)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, void *addr, size_t size,
+                      debug_callback_t callback, void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+  static bool g_debug_initiliazed = false;
+
+  if (g_debug_initiliazed == false)
+    {
+      riscv_debug_init();
+      g_debug_initiliazed = true;
+    }
+
+  /* Find a free slot */
+
+  slot = riscv_debug_find_slot(0, 0, 0);
+
+  if (slot < 0)
+    {
+      return slot;
+    }
+
+  /* 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 = DMODE_TYPE_BOTH;
+  mc.action = ACTION_TYPE_EXCEPTION;
+
+  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
+    {
+      /* DEBUGPOINT_STEPPOINT is not supported since current test platform
+       * such as QEMU don't implemented yet.
+       */
+
+      ret = -ENOTSUP;
+      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 = MATCH_TYPE_TOPBITS;
+      addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                    ((size - 1) >> 1);
+      WRITE_CSR(CSR_TDATA2, addr_napot);
+    }
+  else
+    {
+      mc.match = MATCH_TYPE_EQUAL;
+      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_MPTE | TCONTROL_MTE);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_debugpoint_remove
+ ****************************************************************************/
+
+int up_debugpoint_remove(int type, void *addr, size_t size)
+{
+  int slot;
+
+  /* Find the existing debugpoint */
+
+  slot = riscv_debug_find_slot(type, addr, size);
+
+  if (slot < 0)
+    {
+      return slot;
+    }
+
+  /* Select the trigger and clear setting by write 0 to tdata1 */
+
+  WRITE_CSR(CSR_TSELECT, slot);
+

Review Comment:
   remove



##########
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:
   But it's always to good to follow the current practice.



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */
+#define TRIGGER_TYPE_LEGACY_SIFIVE 1 /* Legacy SiFive address match trigger */
+#define TRIGGER_TYPE_ADDRESS_DATA 2  /* Address/data match trigger */
+#define TRIGGER_TYPE_ICOUNT 3        /* Instruction count trigger */
+#define TRIGGER_TYPE_ITRIGGER 4      /* Interrupt trigger */
+#define TRIGGER_TYPE_ETRIGGER 5      /* Exception trigger */
+
+#define MATCH_TYPE_EQUAL 0     /* Value equals to tdata2 */
+#define MATCH_TYPE_TOPBITS 1   /* Match top M bits of tdata2 */
+#define MATCH_TYPE_GREAT 2     /* Value great than tdata2 */
+#define MATCH_TYPE_LESS 3      /* Value less than tdata2 */
+#define MATCH_TYPE_LOWERHALF 4 /* Lower half of the value equals */
+#define MATCH_TYPE_UPPERHALF 5 /* Upper half of the value equals */
+
+#define ACTION_TYPE_EXCEPTION 0 /* Raise a breakpoint exception */
+#define ACTION_TYPE_DEBUGMODE 1 /* Enter debug mode */
+
+#define DMODE_TYPE_BOTH 0 /* Both Debug and M-mode can write the tdata */
+#define DMODE_TYPE_ONLY 1 /* Only Debug Mode can write the tdata */
+
+/****************************************************************************
+ * 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 riscv_debug_find_slot(int type, void *address, size_t size)
+{
+  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)
+        {
+          return i;
+        }
+    }
+
+  return -ENOENT;
+}
+
+static int riscv_debug_handler(int irq, void *context, 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: riscv_debug_init
+ ****************************************************************************/
+
+void riscv_debug_init(void)
+{
+  union mcontrol mc;
+
+  /* Attach the debug exception handler */
+
+  irq_attach(RISCV_IRQ_BPOINT, riscv_debug_handler, NULL);
+
+  /* Detect the support of NAPOT by trigger 0 */
+
+  WRITE_CSR(CSR_TSELECT, 0);
+
+  mc.reg = READ_CSR(CSR_TDATA1);
+
+  /* REVISIT: NAPOT match is supported and tested on
+   * QEMU and ESP32C3, prefer to use it.
+   */
+
+  mc.match = MATCH_TYPE_TOPBITS;
+
+  /* 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 == MATCH_TYPE_TOPBITS)
+    {
+      g_support_napot = true;
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_debugpoint_add
+ ****************************************************************************/
+
+int up_debugpoint_add(int type, void *addr, size_t size,
+                      debug_callback_t callback, void *arg)
+{
+  int slot;
+  union mcontrol mc;
+  int ret = OK;
+  uintptr_t addr_napot;
+  static bool g_debug_initiliazed = false;
+
+  if (g_debug_initiliazed == false)
+    {
+      riscv_debug_init();
+      g_debug_initiliazed = true;
+    }
+
+  /* Find a free slot */
+
+  slot = riscv_debug_find_slot(0, 0, 0);
+
+  if (slot < 0)
+    {
+      return slot;
+    }
+
+  /* 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 = DMODE_TYPE_BOTH;
+  mc.action = ACTION_TYPE_EXCEPTION;
+
+  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
+    {
+      /* DEBUGPOINT_STEPPOINT is not supported since current test platform
+       * such as QEMU don't implemented yet.
+       */
+
+      ret = -ENOTSUP;
+      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 = MATCH_TYPE_TOPBITS;
+      addr_napot = ((uintptr_t)addr & ~(size - 1)) |
+                    ((size - 1) >> 1);
+      WRITE_CSR(CSR_TDATA2, addr_napot);
+    }
+  else
+    {
+      mc.match = MATCH_TYPE_EQUAL;
+      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_MPTE | TCONTROL_MTE);

Review Comment:
   should we move to 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 */
+#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:
   what's behavior if the following code execute 



##########
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:
   The spec doesn't define the standard way to query NR_IRQ, but trigger number 
has one, why not do some simple detection in riscv_debug_init, which will 
simplify the user a lot.



##########
arch/risc-v/src/common/riscv_debug.c:
##########
@@ -0,0 +1,386 @@
+/****************************************************************************
+ * 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 */
+
+#define TRIGGER_TYPE_NONE 0          /* There is no trigger at this tselect */

Review Comment:
   let's algin the second column with each other



-- 
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