You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/13 01:09:26 UTC

(nuttx) 01/13: coresight: add coresight_core

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

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

commit 24050ba59ff556000a878e8d02af34f9465111a8
Author: liaoao <li...@xiaomi.com>
AuthorDate: Fri Sep 15 19:33:41 2023 +0800

    coresight: add coresight_core
    
    Signed-off-by: liaoao <li...@xiaomi.com>
---
 Kconfig                             |  33 ++
 drivers/Kconfig                     |   1 +
 drivers/Makefile                    |   1 +
 drivers/coresight/CMakeLists.txt    |  25 ++
 drivers/coresight/Kconfig           |  18 +
 drivers/coresight/Make.defs         |  31 ++
 drivers/coresight/coresight_core.c  | 687 ++++++++++++++++++++++++++++++++++++
 include/debug.h                     |  18 +
 include/nuttx/coresight/coresight.h | 241 +++++++++++++
 9 files changed, 1055 insertions(+)

diff --git a/Kconfig b/Kconfig
index 397ad247c4..f700eeeb4c 100644
--- a/Kconfig
+++ b/Kconfig
@@ -2284,6 +2284,39 @@ config DEBUG_RPMSG_INFO
 		Enable RPMSG driver informational output to SYSLOG.
 
 endif # DEBUG_RPMSG
+
+config DEBUG_CORESIGHT
+	bool "Coresight Debug Features"
+	default n
+	depends on CORESIGHT
+	---help---
+		Enable coresight debug features.
+
+if DEBUG_CORESIGHT
+
+config DEBUG_CORESIGHT_ERROR
+	bool "Coresight Error Output"
+	default n
+	depends on DEBUG_ERROR
+	---help---
+		Enable coresight driver error output to SYSLOG.
+
+config DEBUG_CORESIGHT_WARN
+	bool "Coresight Warnings Output"
+	default n
+	depends on DEBUG_WARN
+	---help---
+		Enable coresight warning output to SYSLOG.
+
+config DEBUG_CORESIGHT_INFO
+	bool "Coresight Informational Output"
+	default n
+	depends on DEBUG_INFO
+	---help---
+		Enable coresight driver informational output to SYSLOG.
+
+endif # DEBUG_CORESIGHT
+
 endif # DEBUG_FEATURES
 
 config ARCH_HAVE_STACKCHECK
diff --git a/drivers/Kconfig b/drivers/Kconfig
index fe95fa7600..46ddf14cf1 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -60,3 +60,4 @@ source "drivers/dma/Kconfig"
 source "drivers/devicetree/Kconfig"
 source "drivers/reset/Kconfig"
 source "drivers/pci/Kconfig"
+source "drivers/coresight/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index e5344abc07..1461e7f223 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -78,6 +78,7 @@ include segger/Make.defs
 include usrsock/Make.defs
 include reset/Make.defs
 include pci/Make.defs
+include coresight/Make.defs
 
 ifeq ($(CONFIG_SPECIFIC_DRIVERS),y)
 -include platform/Make.defs
diff --git a/drivers/coresight/CMakeLists.txt b/drivers/coresight/CMakeLists.txt
new file mode 100644
index 0000000000..6205709727
--- /dev/null
+++ b/drivers/coresight/CMakeLists.txt
@@ -0,0 +1,25 @@
+# ##############################################################################
+# drivers/coresight/CMakeLists.txt
+#
+# 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.
+#
+# ##############################################################################
+
+if(CONFIG_CORESIGHT)
+  set(SRCS coresight_core.c)
+
+  target_sources(drivers PRIVATE ${SRCS})
+endif()
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
new file mode 100644
index 0000000000..73274a0682
--- /dev/null
+++ b/drivers/coresight/Kconfig
@@ -0,0 +1,18 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+menuconfig CORESIGHT
+	bool "Coresight Driver Support"
+	default n
+	---help---
+		Coresight drivers support.
+
+if CORESIGHT
+
+config CORESIGHT_MAX_OUTPORT_NUM
+	int "Max outport number of coresight device"
+	default 2
+
+endif # CORESIGHT
diff --git a/drivers/coresight/Make.defs b/drivers/coresight/Make.defs
new file mode 100644
index 0000000000..9152b10cf0
--- /dev/null
+++ b/drivers/coresight/Make.defs
@@ -0,0 +1,31 @@
+############################################################################
+# drivers/coresight/Make.defs
+#
+# 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.
+#
+############################################################################
+
+# Include coresight driver build surrport
+
+ifeq ($(CONFIG_CORESIGHT),y)
+
+CSRCS += coresight_core.c
+
+DEPPATH += --dep-path coresight
+VPATH += :coresight
+CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)drivers$(DELIM)coresight
+
+endif # CONFIG_CORESIGHT
diff --git a/drivers/coresight/coresight_core.c b/drivers/coresight/coresight_core.c
new file mode 100644
index 0000000000..54e6f3e7c8
--- /dev/null
+++ b/drivers/coresight/coresight_core.c
@@ -0,0 +1,687 @@
+/****************************************************************************
+ * drivers/coresight/coresight_core.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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <debug.h>
+#include <stdbool.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/irq.h>
+
+#include <nuttx/coresight/coresight.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Used for build path */
+
+struct coresight_node_s
+{
+  FAR struct coresight_dev_s *csdev;
+  struct list_node link;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct list_node g_csdev_list = LIST_INITIAL_VALUE(g_csdev_list);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: coresight_enable_sink
+ ****************************************************************************/
+
+static int coresight_enable_sink(FAR struct coresight_dev_s *csdev)
+{
+  if (csdev->ops->sink_ops->enable != NULL)
+    {
+      return csdev->ops->sink_ops->enable(csdev);
+    }
+  else
+    {
+      return -EINVAL;
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_disable_sink
+ ****************************************************************************/
+
+static void coresight_disable_sink(FAR struct coresight_dev_s *csdev)
+{
+  if (csdev->ops->sink_ops->disable != NULL)
+    {
+      csdev->ops->sink_ops->disable(csdev);
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_find_link_inport
+ ****************************************************************************/
+
+static int coresight_find_link_inport(FAR struct coresight_dev_s *csdev,
+                                      FAR struct coresight_dev_s *prev)
+{
+  FAR struct coresight_connect_s *conn;
+  int i;
+
+  for (i = 0; i < prev->outport_num; i++)
+    {
+      conn = &prev->outconns[i];
+      if (conn->destdev == csdev)
+        {
+          return conn->destport;
+        }
+    }
+
+  return -ENODEV;
+}
+
+/****************************************************************************
+ * Name: coresight_find_link_outport
+ ****************************************************************************/
+
+static int coresight_find_link_outport(FAR struct coresight_dev_s *csdev,
+                                       FAR struct coresight_dev_s *next)
+{
+  FAR struct coresight_connect_s *conn;
+  int i;
+
+  for (i = 0; i < csdev->outport_num; i++)
+    {
+      conn = &csdev->outconns[i];
+      if (conn->destdev == next)
+        {
+          return conn->srcport;
+        }
+    }
+
+  return -ENODEV;
+}
+
+/****************************************************************************
+ * Name: coresight_enable_link
+ ****************************************************************************/
+
+static int coresight_enable_link(FAR struct coresight_dev_s *csdev,
+                                 FAR struct coresight_dev_s *prev,
+                                 FAR struct coresight_dev_s *next)
+{
+  int inport = 0;
+  int outport = 0;
+
+  if (csdev->ops->link_ops->enable == NULL)
+    {
+      return -EINVAL;
+    }
+
+  if (csdev->subtype.link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
+    {
+      inport = coresight_find_link_inport(csdev, prev);
+      if (inport < 0)
+        {
+          return inport;
+        }
+    }
+
+  if (csdev->subtype.link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
+    {
+      outport = coresight_find_link_outport(csdev, next);
+      if (outport < 0)
+        {
+          return outport;
+        }
+    }
+
+  return csdev->ops->link_ops->enable(csdev, inport, outport);
+}
+
+/****************************************************************************
+ * Name: coresight_disable_link
+ ****************************************************************************/
+
+static void coresight_disable_link(FAR struct coresight_dev_s *csdev,
+                                   FAR struct coresight_dev_s *prev,
+                                   FAR struct coresight_dev_s *next)
+{
+  if (csdev->ops->sink_ops->disable != NULL)
+    {
+      int inport = coresight_find_link_inport(csdev, prev);
+      int outport = coresight_find_link_outport(csdev, next);
+      csdev->ops->link_ops->disable(csdev, inport, outport);
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_enable_source
+ ****************************************************************************/
+
+static int coresight_enable_source(FAR struct coresight_dev_s *csdev)
+{
+  if (csdev->ops->source_ops->enable != NULL)
+    {
+      return csdev->ops->source_ops->enable(csdev);
+    }
+  else
+    {
+      return -EINVAL;
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_disable_source
+ ****************************************************************************/
+
+static void coresight_disable_source(FAR struct coresight_dev_s *csdev)
+{
+  if (csdev->ops->source_ops->disable != NULL)
+    {
+      csdev->ops->source_ops->disable(csdev);
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_validate_source
+ *
+ * Description:
+ *   Indicate if this coresight device is a valid source device.
+ *
+ ****************************************************************************/
+
+static int coresight_validate_source(FAR struct coresight_dev_s *csdev)
+{
+  uint8_t type = csdev->type;
+  uint8_t subtype = csdev->subtype.source_subtype;
+
+  if (type != CORESIGHT_DEV_TYPE_SOURCE)
+    {
+      cserr("not a source coresight device\n");
+      return -EINVAL;
+    }
+
+  if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
+      subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE)
+    {
+      cserr("not a supported subtype of source device\n");
+      return -EINVAL;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: coresight_build_path
+ *
+ * Description:
+ *   Build path from srcdev to destdev.
+ *
+ * Input Parameters:
+ *   srcdev  - Pointer to the source device.
+ *   destdev - Pointer to the destination device.
+ *   path    - Pointer to the path which will save all the coresight devices
+ *             through source device to destination device.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+static int coresight_build_path(FAR struct coresight_dev_s *srcdev,
+                                FAR struct coresight_dev_s *destdev,
+                                FAR struct list_node *path)
+{
+  FAR struct coresight_node_s *node;
+  bool found = false;
+  int i;
+
+  if (srcdev == destdev)
+    {
+      goto out;
+    }
+
+  for (i = 0; i < srcdev->outport_num; i++)
+    {
+      struct coresight_dev_s *csdev = srcdev->outconns[i].destdev;
+      if (csdev && coresight_build_path(csdev, destdev, path) == 0)
+        {
+          found = true;
+          break;
+        }
+    }
+
+  if (!found)
+    {
+      return -ENODEV;
+    }
+
+out:
+  node = kmm_malloc(sizeof(struct coresight_node_s));
+  if (node == NULL)
+    {
+      return -ENOMEM;
+    }
+
+  node->csdev = srcdev;
+  list_add_head(path, &node->link);
+  return 0;
+}
+
+/****************************************************************************
+ * Name: coresight_release_path
+ *
+ * Description:
+ *   Release memory malloced through the path.
+ *
+ ****************************************************************************/
+
+static void coresight_release_path(FAR struct list_node *path)
+{
+  FAR struct coresight_node_s *node;
+  FAR struct coresight_node_s *next;
+
+  list_for_every_entry_safe(path, node, next, struct coresight_node_s, link)
+    {
+      list_delete(&node->link);
+      kmm_free(node);
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_disable_dev
+ ****************************************************************************/
+
+static void coresight_disable_dev(FAR struct coresight_node_s *node)
+{
+  switch (node->csdev->type)
+    {
+      case CORESIGHT_DEV_TYPE_SINK:
+        coresight_disable_sink(node->csdev);
+        break;
+
+      case CORESIGHT_DEV_TYPE_LINK:
+        {
+          FAR struct coresight_node_s *prev =
+            list_prev_entry(node, struct coresight_node_s, link);
+          FAR struct coresight_node_s *next =
+            list_next_entry(node, struct coresight_node_s, link);
+          coresight_disable_link(node->csdev, prev->csdev, next->csdev);
+        }
+        break;
+
+      /* We skip the first node in the path assuming that it is the source,
+       * and it will be disabled in coresight_disable. So we don't expect a
+       * source device in the middle of a path.
+       */
+
+      default:
+        DEBUGASSERT(0);
+        break;
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_disable_path_from
+ *
+ * Description:
+ *   Disable coresight devices from specific node.
+ *
+ * Input Parameters:
+ *   path  - Head of the path.
+ *   node  - Start position to search, it begins from next of this node to
+ *           disable.
+ *
+ ****************************************************************************/
+
+static void coresight_disable_path_from(FAR struct list_node *path,
+                                        FAR struct coresight_node_s *node)
+{
+  list_for_every_entry_continue(node, path, struct coresight_node_s, link)
+    {
+      coresight_disable_dev(node);
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_disable_path
+ *
+ * Description:
+ *   Disable all the coresight devices through the path except source device.
+ *   Source device will be disabled by coresight_disable or perf end
+ *   function.
+ *
+ ****************************************************************************/
+
+static void coresight_disable_path(FAR struct list_node *path)
+{
+  coresight_disable_path_from(path,
+    container_of(path->next, struct coresight_node_s, link));
+}
+
+/****************************************************************************
+ * Name: coresight_enable_path
+ *
+ * Description:
+ *   Enable all coresight devices through the path in reverse order.
+ *
+ * Input Parameters:
+ *   path  - path from source device to sink device.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+static int coresight_enable_path(FAR struct list_node *path)
+{
+  FAR struct coresight_node_s *node;
+  int ret = 0;
+
+  list_for_every_entry_reverse(path, node, struct coresight_node_s, link)
+    {
+      switch (node->csdev->type)
+        {
+          /* Sink device is the first device to be enable. No need to disable
+           * other coresight device in the path if it enabled failed.
+           */
+
+          case CORESIGHT_DEV_TYPE_SINK:
+            ret = coresight_enable_sink(node->csdev);
+            if (ret < 0)
+              {
+                cserr("enalbe sink: %s failed ret: %d\n",
+                      node->csdev->name, ret);
+                return ret;
+              }
+            break;
+
+          case CORESIGHT_DEV_TYPE_LINK:
+            {
+              FAR struct coresight_node_s *prev =
+                list_prev_entry(node, struct coresight_node_s, link);
+              FAR struct coresight_node_s *next =
+                list_next_entry(node, struct coresight_node_s, link);
+              ret = coresight_enable_link(node->csdev, prev->csdev,
+                                          next->csdev);
+              if (ret < 0)
+                {
+                  cserr("enalbe link: %s failed ret: %d\n",
+                        node->csdev->name, ret);
+                  goto err;
+                }
+            }
+            break;
+
+          /* Source device will be enabled in coresight_enable or
+           * perf start function.
+           */
+
+          case CORESIGHT_DEV_TYPE_SOURCE:
+            break;
+
+          default:
+            cserr("invalid coresight device type through the path\n");
+            DEBUGASSERT(0);
+            goto err;
+      }
+    }
+
+  return ret;
+
+err:
+  coresight_disable_path_from(path, node);
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: coresight_register
+ *
+ * Description:
+ *   Register a coresight device to the coresight bus.
+ *
+ * Input Parameters:
+ *   csdev  - Pointer to the coresight device that needs to be registered.
+ *   desc   - Pointer to the attribute description of this coresight device.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+int coresight_register(FAR struct coresight_dev_s *csdev,
+                       FAR const struct coresight_desc_s *desc)
+{
+  FAR struct coresight_dev_s *tempdev;
+  irqstate_t flags;
+  int i;
+
+  csdev->name = desc->name;
+  csdev->addr = desc->addr;
+  csdev->type = desc->type;
+  csdev->subtype = desc->subtype;
+  csdev->outport_num = desc->outport_num;
+  list_initialize(&csdev->path);
+
+  if (csdev->outport_num > 0)
+    {
+      csdev->outconns =
+        kmm_zalloc(sizeof(struct coresight_connect_s) * desc->outport_num);
+      if (csdev->outconns == NULL)
+        {
+          return -ENOMEM;
+        }
+
+      for (i = 0; i < csdev->outport_num; i++)
+        {
+          FAR struct coresight_connect_s *conn = &csdev->outconns[i];
+          FAR const struct coresight_portdesc_s *portdesc =
+            &desc->outports[i];
+
+          conn->srcport = i;
+          conn->destport = portdesc->port;
+          conn->destname = portdesc->remote;
+          conn->srcdev = csdev;
+        }
+    }
+
+  flags = enter_critical_section();
+  list_for_every_entry(&g_csdev_list, tempdev, struct coresight_dev_s, node)
+    {
+      for (i = 0; i < tempdev->outport_num; i++)
+        {
+          FAR struct coresight_connect_s *conn = &tempdev->outconns[i];
+          if (strcmp(conn->destname, csdev->name) == 0)
+            {
+              conn->destdev = csdev;
+            }
+        }
+
+      for (i = 0; i < csdev->outport_num; i++)
+        {
+          FAR struct coresight_connect_s *conn = &csdev->outconns[i];
+          if (strcmp(conn->destname, tempdev->name) == 0)
+            {
+              conn->destdev = tempdev;
+            }
+        }
+    }
+
+  list_add_tail(&g_csdev_list, &csdev->node);
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: coresight_unregister
+ *
+ * Description:
+ *   Unregister a coresight device from coresight bus.
+ *
+ * Input Parameters:
+ *   csdev  - Pointer to the coresight device that needs to be unregistered.
+ *
+ ****************************************************************************/
+
+void coresight_unregister(FAR struct coresight_dev_s *csdev)
+{
+  FAR struct coresight_dev_s *tempdev;
+  irqstate_t flags;
+  int i;
+
+  flags = enter_critical_section();
+  list_for_every_entry(&g_csdev_list, tempdev, struct coresight_dev_s, node)
+    {
+      if (csdev == tempdev)
+        {
+          continue;
+        }
+
+      for (i = 0; i < tempdev->outport_num; i++)
+        {
+          FAR struct coresight_connect_s *conn = &tempdev->outconns[i];
+          if (conn->destdev == csdev)
+            {
+              conn->destdev = NULL;
+            }
+        }
+    }
+
+  list_delete(&csdev->node);
+  leave_critical_section(flags);
+
+  if (csdev->outport_num > 0)
+    {
+      kmm_free(csdev->outconns);
+      csdev->outconns = NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: coresight_enable
+ *
+ * Description:
+ *   Enable trace start from srcdev to destdev.
+ *
+ * Input Parameters:
+ *   srcdev  - Source device that generates trace data.
+ *   destdev - Sink device that finally accepts the trace data.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+int coresight_enable(FAR struct coresight_dev_s *srcdev,
+                     FAR struct coresight_dev_s *destdev)
+{
+  FAR struct coresight_node_s *node;
+  irqstate_t flags;
+  int ret;
+
+  ret = coresight_validate_source(srcdev);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  flags = enter_critical_section();
+
+  if (list_is_empty(&srcdev->path))
+    {
+      ret = coresight_build_path(srcdev, destdev, &srcdev->path);
+      if (ret < 0)
+        {
+          cserr("build path failed from %s ret: %d\n", srcdev->name, ret);
+          goto err_path;
+        }
+    }
+
+  ret = coresight_enable_path(&srcdev->path);
+  if (ret < 0)
+    {
+      cserr("enable path failed from %s ret: %d\n", srcdev->name, ret);
+      goto err_path;
+    }
+
+  ret = coresight_enable_source(srcdev);
+  if (ret < 0)
+    {
+      cserr("enable source failed %s ret: %d\n", srcdev->name, ret);
+      goto err_source;
+    }
+
+  csinfo("trace enabled success while devices are:");
+  list_for_every_entry(&srcdev->path, node, struct coresight_node_s, link)
+    {
+      csinfo("-> %s", node->csdev->name);
+    }
+
+out:
+  leave_critical_section(flags);
+  return ret;
+
+err_source:
+  coresight_disable_path(&srcdev->path);
+
+err_path:
+  coresight_release_path(&srcdev->path);
+  goto out;
+}
+
+/****************************************************************************
+ * Name: coresight_disable
+ *
+ * Description:
+ *   Disable the trace start from srcdev to destdev.
+ *
+ * Input Parameters:
+ *   srcdev  - Source device that generates trace data.
+ *
+ ****************************************************************************/
+
+void coresight_disable(FAR struct coresight_dev_s *srcdev)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  coresight_disable_source(srcdev);
+  coresight_disable_path(&srcdev->path);
+  coresight_release_path(&srcdev->path);
+
+  leave_critical_section(flags);
+}
+
diff --git a/include/debug.h b/include/debug.h
index 2567b01a73..418ecc6fb6 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -956,6 +956,24 @@
 #  define rpmsginfo     _none
 #endif
 
+#ifdef CONFIG_DEBUG_CORESIGHT_ERROR
+#  define cserr       _err
+#else
+#  define cserr      _none
+#endif
+
+#ifdef CONFIG_DEBUG_CORESIGHT_WARN
+#  define cswarn     _warn
+#else
+#  define cswarn     _none
+#endif
+
+#ifdef CONFIG_DEBUG_CORESIGHT_INFO
+#  define csinfo     _info
+#else
+#  define csinfo     _none
+#endif
+
 /* Buffer dumping macros do not depend on varargs */
 
 #ifdef CONFIG_DEBUG_ERROR
diff --git a/include/nuttx/coresight/coresight.h b/include/nuttx/coresight/coresight.h
new file mode 100644
index 0000000000..2630e81633
--- /dev/null
+++ b/include/nuttx/coresight/coresight.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+ * include/nuttx/coresight/coresight.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_CORESIGHT_CORESIGHT_H
+#define __INCLUDE_NUTTX_CORESIGHT_CORESIGHT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <nuttx/list.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+enum coresight_dev_type_e
+{
+  CORESIGHT_DEV_TYPE_SOURCE,
+  CORESIGHT_DEV_TYPE_LINK,
+  CORESIGHT_DEV_TYPE_SINK,
+  CORESIGHT_DEV_TYPE_MAX
+};
+
+enum coresight_dev_subtype_source_e
+{
+  CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,       /* ETM */
+  CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,   /* STM */
+};
+
+enum coresight_dev_subtype_link_e
+{
+  CORESIGHT_DEV_SUBTYPE_LINK_MERG,         /* Funnel */
+  CORESIGHT_DEV_SUBTYPE_LINK_SPLIT,        /* Replocator */
+  CORESIGHT_DEV_SUBTYPE_LINK_FIFO,         /* TMC ETR */
+};
+
+enum coresight_dev_subtype_sink_e
+{
+  CORESIGHT_DEV_SUBTYPE_SINK_PORT,         /* TPIU */
+  CORESIGHT_DEV_SUBTYPE_SINK_BUFFER,       /* ETB */
+};
+
+/* This structure is used to unify different subtype of devices. */
+
+union coresight_dev_subtype_u
+{
+  enum coresight_dev_subtype_source_e source_subtype;
+  enum coresight_dev_subtype_link_e link_subtype;
+  enum coresight_dev_subtype_sink_e sink_subtype;
+};
+
+struct coresight_dev_s;
+
+struct coresight_sink_ops_s
+{
+  int (*enable)(FAR struct coresight_dev_s *csdev);
+  void (*disable)(FAR struct coresight_dev_s *csdev);
+};
+
+struct coresight_link_ops_s
+{
+  int (*enable)(FAR struct coresight_dev_s *csdev, int iport, int oport);
+  void (*disable)(FAR struct coresight_dev_s *csdev, int iport, int oport);
+};
+
+struct coresight_source_ops_s
+{
+  int (*enable)(FAR struct coresight_dev_s *csdev);
+  void (*disable)(FAR struct coresight_dev_s *csdev);
+};
+
+/* This structure is used to unify different operations of devices. */
+
+struct coresight_ops_s
+{
+  union
+    {
+      FAR const struct coresight_sink_ops_s *sink_ops;
+      FAR const struct coresight_link_ops_s *link_ops;
+      FAR const struct coresight_source_ops_s *source_ops;
+    };
+};
+
+struct coresight_portdesc_s
+{
+  /* Coresight device's name this port connects to. */
+
+  FAR const char *remote;
+
+  /* Port connects to. */
+
+  int port;
+};
+
+struct coresight_desc_s
+{
+  FAR const char *name;
+  uintptr_t addr;
+  enum coresight_dev_type_e type;
+  union coresight_dev_subtype_u subtype;
+
+  /* Description of outports of current device. */
+
+  int outport_num;
+  struct coresight_portdesc_s outports[CONFIG_CORESIGHT_MAX_OUTPORT_NUM];
+};
+
+/* Use to build the trace path. */
+
+struct coresight_connect_s
+{
+  int srcport;
+  int destport;
+
+  /* Used to find the dest device when build the trace path. */
+
+  FAR const char *destname;
+  FAR struct coresight_dev_s *srcdev;
+  FAR struct coresight_dev_s *destdev;
+};
+
+struct coresight_dev_s
+{
+  FAR const char *name;
+
+  /* Memory-mapped base address of current coresight device. */
+
+  uintptr_t addr;
+  enum coresight_dev_type_e type;
+  union coresight_dev_subtype_u subtype;
+  FAR const struct coresight_ops_s *ops;
+
+  /* Used to connect all the coresight device register to coresight bus. */
+
+  struct list_node node;
+
+  /* Used in source coresight device as trace path's list head. */
+
+  struct list_node path;
+
+  /* Out port number current coresight device have. */
+
+  int outport_num;
+
+  /* Pointer to an array of connections, array size is equal
+   * to the outport number.
+   */
+
+  FAR struct coresight_connect_s *outconns;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: coresight_register
+ *
+ * Description:
+ *   Register a coresight device to the coresight bus.
+ *
+ * Input Parameters:
+ *   csdev  - Pointer to the coresight device that needs to be registered.
+ *   desc   - Pointer to the attribute description of this coresight device.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+int coresight_register(FAR struct coresight_dev_s *csdev,
+                       FAR const struct coresight_desc_s *desc);
+
+/****************************************************************************
+ * Name: coresight_unregister
+ *
+ * Description:
+ *   Unregister a coresight device from coresight bus.
+ *
+ * Input Parameters:
+ *   csdev  - Pointer to the coresight device that needs to be unregistered.
+ *
+ ****************************************************************************/
+
+void coresight_unregister(FAR struct coresight_dev_s *csdev);
+
+/****************************************************************************
+ * Name: coresight_enable
+ *
+ * Description:
+ *   Enable trace start from srcdev to destdev.
+ *
+ * Input Parameters:
+ *   srcdev  - Source device that generates trace data.
+ *   destdev - Sink device that finally accepts the trace data.
+ *
+ * Returned Value:
+ *   Zero on success; a negative value on failure.
+ *
+ ****************************************************************************/
+
+int coresight_enable(FAR struct coresight_dev_s *srcdev,
+                     FAR struct coresight_dev_s *destdev);
+
+/****************************************************************************
+ * Name: coresight_disable
+ *
+ * Description:
+ *   Disable the trace start from srcdev to destdev.
+ *
+ * Input Parameters:
+ *   srcdev  - Source device that generates trace data.
+ *
+ ****************************************************************************/
+
+void coresight_disable(FAR struct coresight_dev_s *srcdev);
+
+#endif  /* __INCLUDE_NUTTX_CORESIGHT_CORESIGHT_H */