2 * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com>
5 * This software was developed by SRI International and the University of
6 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
7 * ("CTSRD"), as part of the DARPA CRASH research programme.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <machine/bus.h>
42 #include <arm64/coresight/coresight.h>
44 #include "coresight_if.h"
46 extern struct coresight_device_list cs_devs;
48 static struct coresight_device *
49 coresight_next_device(struct coresight_device *cs_dev,
50 struct coresight_event *event)
52 struct coresight_device *out;
53 struct endpoint *out_endp;
54 struct endpoint *endp;
56 TAILQ_FOREACH(endp, &cs_dev->pdata->endpoints, link) {
60 out = coresight_get_output_device(endp, &out_endp);
62 if (LIST_EMPTY(&event->endplist)) {
63 /* Add source device */
64 endp->cs_dev = cs_dev;
65 LIST_INSERT_HEAD(&event->endplist, endp,
69 /* Add output device */
71 printf("Adding device %s to the chain\n",
72 device_get_nameunit(out->dev));
73 out_endp->cs_dev = out;
74 LIST_INSERT_HEAD(&event->endplist, out_endp, endplink);
84 coresight_build_list(struct coresight_device *cs_dev,
85 struct coresight_event *event)
87 struct coresight_device *out;
91 out = coresight_next_device(out, event);
97 coresight_init_event(int cpu, struct coresight_event *event)
99 struct coresight_device *cs_dev;
100 struct endpoint *endp;
102 /* Start building path from source device */
103 TAILQ_FOREACH(cs_dev, &cs_devs, link) {
104 if (cs_dev->dev_type == event->src &&
105 cs_dev->pdata->cpu == cpu) {
106 LIST_INIT(&event->endplist);
107 coresight_build_list(cs_dev, event);
112 /* Ensure Coresight is initialized for the CPU */
113 TAILQ_FOREACH(cs_dev, &cs_devs, link) {
114 if (cs_dev->dev_type == CORESIGHT_CPU_DEBUG &&
115 cs_dev->pdata->cpu == cpu)
116 CORESIGHT_INIT(cs_dev->dev);
119 /* Init all devices in the path */
120 LIST_FOREACH(endp, &event->endplist, endplink) {
121 cs_dev = endp->cs_dev;
122 CORESIGHT_INIT(cs_dev->dev);
129 coresight_enable(int cpu, struct coresight_event *event)
131 struct coresight_device *cs_dev;
132 struct endpoint *endp;
134 LIST_FOREACH(endp, &event->endplist, endplink) {
135 cs_dev = endp->cs_dev;
136 CORESIGHT_ENABLE(cs_dev->dev, endp, event);
141 coresight_disable(int cpu, struct coresight_event *event)
143 struct coresight_device *cs_dev;
144 struct endpoint *endp;
146 LIST_FOREACH(endp, &event->endplist, endplink) {
147 cs_dev = endp->cs_dev;
148 CORESIGHT_DISABLE(cs_dev->dev, endp, event);
153 coresight_read(int cpu, struct coresight_event *event)
155 struct endpoint *endp;
157 LIST_FOREACH(endp, &event->endplist, endplink)
158 CORESIGHT_READ(endp->cs_dev->dev, endp, event);