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