From 24050ba59ff556000a878e8d02af34f9465111a8 Mon Sep 17 00:00:00 2001 From: liaoao Date: Fri, 15 Sep 2023 19:33:41 +0800 Subject: [PATCH] coresight: add coresight_core Signed-off-by: liaoao --- 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(+) create mode 100644 drivers/coresight/CMakeLists.txt create mode 100644 drivers/coresight/Kconfig create mode 100644 drivers/coresight/Make.defs create mode 100644 drivers/coresight/coresight_core.c create mode 100644 include/nuttx/coresight/coresight.h 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 +#include +#include +#include +#include + +#include + +/**************************************************************************** + * 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 +#include + +/**************************************************************************** + * 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 */