diff --git a/sys/arm64/coresight/coresight.c b/sys/arm64/coresight/coresight.c
index 3fd4a5f233d1..38a47c0c3b0f 100644
--- a/sys/arm64/coresight/coresight.c
+++ b/sys/arm64/coresight/coresight.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -41,78 +41,11 @@ __FBSDID("$FreeBSD$");
#include
#include
-#include
-#include
-
#include
-MALLOC_DEFINE(M_CORESIGHT, "coresight", "ARM Coresight");
static struct mtx cs_mtx;
-
struct coresight_device_list cs_devs;
-static int
-coresight_get_ports(phandle_t dev_node,
- struct coresight_platform_data *pdata)
-{
- phandle_t node, child;
- pcell_t port_reg;
- phandle_t xref;
- char *name;
- int ret;
- phandle_t endpoint_child;
- struct endpoint *endp;
-
- child = ofw_bus_find_child(dev_node, "ports");
- if (child)
- node = child;
- else
- node = dev_node;
-
- for (child = OF_child(node); child != 0; child = OF_peer(child)) {
- ret = OF_getprop_alloc(child, "name", (void **)&name);
- if (ret == -1)
- continue;
-
- if (strcasecmp(name, "port") ||
- strncasecmp(name, "port@", 6)) {
-
- port_reg = -1;
- OF_getencprop(child, "reg", (void *)&port_reg,
- sizeof(port_reg));
-
- endpoint_child = ofw_bus_find_child(child, "endpoint");
- if (endpoint_child) {
- if (OF_getencprop(endpoint_child,
- "remote-endpoint", &xref,
- sizeof(xref)) == -1) {
- printf("failed\n");
- continue;
- }
- endp = malloc(sizeof(struct endpoint),
- M_CORESIGHT, M_WAITOK | M_ZERO);
- endp->my_node = endpoint_child;
- endp->their_node = OF_node_from_xref(xref);
- endp->dev_node = dev_node;
- endp->reg = port_reg;
- if (OF_getproplen(endpoint_child,
- "slave-mode") >= 0) {
- pdata->in_ports++;
- endp->slave = 1;
- } else
- pdata->out_ports++;
-
- mtx_lock(&pdata->mtx_lock);
- TAILQ_INSERT_TAIL(&pdata->endpoints,
- endp, link);
- mtx_unlock(&pdata->mtx_lock);
- }
- }
- }
-
- return (0);
-}
-
int
coresight_register(struct coresight_desc *desc)
{
@@ -121,7 +54,6 @@ coresight_register(struct coresight_desc *desc)
cs_dev = malloc(sizeof(struct coresight_device),
M_CORESIGHT, M_WAITOK | M_ZERO);
cs_dev->dev = desc->dev;
- cs_dev->node = ofw_bus_get_node(desc->dev);
cs_dev->pdata = desc->pdata;
cs_dev->dev_type = desc->dev_type;
@@ -141,7 +73,7 @@ coresight_get_output_endpoint(struct coresight_platform_data *pdata)
return (NULL);
TAILQ_FOREACH(endp, &pdata->endpoints, link) {
- if (endp->slave == 0)
+ if (endp->input == 0)
return (endp);
}
@@ -151,14 +83,31 @@ coresight_get_output_endpoint(struct coresight_platform_data *pdata)
struct coresight_device *
coresight_get_output_device(struct endpoint *endp, struct endpoint **out_endp)
{
+ struct coresight_platform_data *pdata;
struct coresight_device *cs_dev;
struct endpoint *endp2;
TAILQ_FOREACH(cs_dev, &cs_devs, link) {
+ pdata = cs_dev->pdata;
TAILQ_FOREACH(endp2, &cs_dev->pdata->endpoints, link) {
- if (endp->their_node == endp2->my_node) {
- *out_endp = endp2;
- return (cs_dev);
+ switch (pdata->bus_type) {
+ case CORESIGHT_BUS_FDT:
+#ifdef FDT
+ if (endp->their_node == endp2->my_node) {
+ *out_endp = endp2;
+ return (cs_dev);
+ }
+#endif
+ break;
+
+ case CORESIGHT_BUS_ACPI:
+#ifdef DEV_ACPI
+ if (endp->their_handle == endp2->my_handle) {
+ *out_endp = endp2;
+ return (cs_dev);
+ }
+#endif
+ break;
}
}
}
@@ -166,49 +115,6 @@ coresight_get_output_device(struct endpoint *endp, struct endpoint **out_endp)
return (NULL);
}
-static int
-coresight_get_cpu(phandle_t node,
- struct coresight_platform_data *pdata)
-{
- phandle_t cpu_node;
- pcell_t xref;
- pcell_t cpu_reg;
-
- if (OF_getencprop(node, "cpu", &xref, sizeof(xref)) != -1) {
- cpu_node = OF_node_from_xref(xref);
- if (OF_getencprop(cpu_node, "reg", (void *)&cpu_reg,
- sizeof(cpu_reg)) > 0) {
- pdata->cpu = cpu_reg;
- return (0);
- }
- }
-
- return (-1);
-}
-
-struct coresight_platform_data *
-coresight_get_platform_data(device_t dev)
-{
- struct coresight_platform_data *pdata;
- phandle_t node;
-
- node = ofw_bus_get_node(dev);
-
- pdata = malloc(sizeof(struct coresight_platform_data),
- M_CORESIGHT, M_WAITOK | M_ZERO);
- mtx_init(&pdata->mtx_lock, "Coresight Platform Data", NULL, MTX_DEF);
- TAILQ_INIT(&pdata->endpoints);
-
- coresight_get_cpu(node, pdata);
- coresight_get_ports(node, pdata);
-
- if (bootverbose)
- printf("Total ports: in %d out %d\n",
- pdata->in_ports, pdata->out_ports);
-
- return (pdata);
-}
-
static void
coresight_init(void)
{
diff --git a/sys/arm64/coresight/coresight.h b/sys/arm64/coresight/coresight.h
index 9ae4db51595e..a3aa71cb207f 100644
--- a/sys/arm64/coresight/coresight.h
+++ b/sys/arm64/coresight/coresight.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -33,7 +33,19 @@
#ifndef _ARM64_CORESIGHT_CORESIGHT_H_
#define _ARM64_CORESIGHT_CORESIGHT_H_
+#include "opt_acpi.h"
+#include "opt_platform.h"
+
+#include
+
+#ifdef FDT
#include
+#endif
+
+#ifdef DEV_ACPI
+#include
+#include
+#endif
#define CORESIGHT_ITCTRL 0xf00
#define CORESIGHT_CLAIMSET 0xfa0
@@ -53,20 +65,30 @@ enum cs_dev_type {
CORESIGHT_CPU_DEBUG,
};
+enum cs_bus_type {
+ CORESIGHT_BUS_ACPI,
+ CORESIGHT_BUS_FDT,
+};
+
struct coresight_device {
TAILQ_ENTRY(coresight_device) link;
device_t dev;
- phandle_t node;
enum cs_dev_type dev_type;
struct coresight_platform_data *pdata;
};
struct endpoint {
TAILQ_ENTRY(endpoint) link;
+#ifdef FDT
phandle_t my_node;
phandle_t their_node;
phandle_t dev_node;
- boolean_t slave;
+#endif
+#ifdef DEV_ACPI
+ ACPI_HANDLE their_handle;
+ ACPI_HANDLE my_handle;
+#endif
+ boolean_t input;
int reg;
struct coresight_device *cs_dev;
LIST_ENTRY(endpoint) endplink;
@@ -78,6 +100,7 @@ struct coresight_platform_data {
int out_ports;
struct mtx mtx_lock;
TAILQ_HEAD(endpoint_list, endpoint) endpoints;
+ enum cs_bus_type bus_type;
};
struct coresight_desc {
@@ -125,7 +148,10 @@ struct etm_config {
uint8_t excp_level;
};
-struct coresight_platform_data * coresight_get_platform_data(device_t dev);
+static MALLOC_DEFINE(M_CORESIGHT, "coresight", "ARM Coresight");
+
+struct coresight_platform_data *coresight_fdt_get_platform_data(device_t dev);
+struct coresight_platform_data *coresight_acpi_get_platform_data(device_t dev);
struct endpoint * coresight_get_output_endpoint(struct coresight_platform_data *pdata);
struct coresight_device * coresight_get_output_device(struct endpoint *endp, struct endpoint **);
int coresight_register(struct coresight_desc *desc);
diff --git a/sys/arm64/coresight/coresight_acpi.c b/sys/arm64/coresight/coresight_acpi.c
new file mode 100644
index 000000000000..57fda8b97666
--- /dev/null
+++ b/sys/arm64/coresight/coresight_acpi.c
@@ -0,0 +1,373 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Ruslan Bukin
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory (Department of Computer Science and
+ * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
+ * DARPA SSITH research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include
+__FBSDID("$FreeBSD$");
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#define ACPI_CORESIGHT_LINK_OUTPUT 1
+#define ACPI_CORESIGHT_LINK_INPUT 0
+
+static const struct uuid acpi_graph_uuid = {
+ 0xab02a46b, 0x74c7, 0x45a2, 0xbd, 0x68,
+ { 0xf7, 0xd3, 0x44, 0xef, 0x21, 0x53 },
+};
+
+static const struct uuid coresight_graph_uuid = {
+ 0x3ecbc8b6, 0x1d0e, 0x4fb3, 0x81, 0x07,
+ { 0xe6, 0x27, 0xf8, 0x05, 0xc6, 0xcd },
+};
+
+static inline bool
+cs_acpi_validate_dsd_graph(const union acpi_object *graph)
+{
+ const union acpi_object *rev, *nr_graphs;
+ const union acpi_object *obj;
+ int i, n;
+
+ if (graph->Package.Count < 2)
+ return (false);
+
+ rev = &graph->Package.Elements[0];
+ nr_graphs = &graph->Package.Elements[1];
+
+ if (rev->Type != ACPI_TYPE_INTEGER ||
+ nr_graphs->Type != ACPI_TYPE_INTEGER)
+ return (false);
+
+ /* Revision 0 supported only. */
+ if (rev->Integer.Value != 0)
+ return (false);
+
+ /* We are looking for a single graph. */
+ n = nr_graphs->Integer.Value;
+ if (n != 1)
+ return (false);
+
+ /* Check the number of elements. */
+ if (graph->Package.Count != (n + 2))
+ return (false);
+
+ for (i = 2; i < n + 2; i++) {
+ obj = &graph->Package.Elements[i];
+ if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count < 3)
+ return (false);
+ }
+
+ return (true);
+}
+
+static inline bool
+cs_is_acpi_guid(const union acpi_object *obj)
+{
+
+ return (obj->Type == ACPI_TYPE_BUFFER) && (obj->Buffer.Length == 16);
+}
+
+static inline bool
+cs_guid_equal(const struct uuid *u1, const struct uuid *u2)
+{
+
+ if (memcmp(u1, u2, 16) == 0)
+ return (true);
+
+ return (false);
+}
+
+static inline bool
+cs_acpi_guid_matches(const union acpi_object *obj, const struct uuid *guid)
+{
+
+ if (cs_is_acpi_guid(obj) &&
+ cs_guid_equal((struct uuid *)obj->Buffer.Pointer, guid))
+ return (true);
+
+ return (false);
+}
+
+static inline bool
+is_acpi_dsd_graph_guid(const union acpi_object *obj)
+{
+
+ return (cs_acpi_guid_matches(obj, &acpi_graph_uuid));
+}
+
+static inline bool
+cs_is_acpi_coresight_graph_guid(const union acpi_object *obj)
+{
+
+ return (cs_acpi_guid_matches(obj, &coresight_graph_uuid));
+}
+
+static inline bool
+cs_is_acpi_coresight_graph(const union acpi_object *obj)
+{
+ const union acpi_object *graphid, *guid, *links;
+
+ if (obj->Type != ACPI_TYPE_PACKAGE ||
+ obj->Package.Count < 3)
+ return (false);
+
+ graphid = &obj->Package.Elements[0];
+ guid = &obj->Package.Elements[1];
+ links = &obj->Package.Elements[2];
+
+ if (graphid->Type != ACPI_TYPE_INTEGER ||
+ links->Type != ACPI_TYPE_INTEGER)
+ return (false);
+
+ if (cs_is_acpi_coresight_graph_guid(guid))
+ return (true);
+
+ return (false);
+}
+
+static const union acpi_object *
+cs_get_dsd_graph(device_t dev)
+{
+ const union acpi_object *guid, *package;
+ union acpi_object *dsd;
+ ACPI_STATUS status;
+ ACPI_BUFFER buf;
+ device_t bus;
+ int i;
+
+ buf.Length = PAGE_SIZE;
+ buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO);
+ if (buf.Pointer == NULL) {
+ printf("Failed to allocate memory.\n");
+ return (NULL);
+ }
+
+ bus = device_get_parent(dev);
+ status = ACPI_EVALUATE_OBJECT(bus, dev, "_DSD", NULL, &buf);
+ if (ACPI_FAILURE(status)) {
+ printf("Failed to evaluate object.\n");
+ return (NULL);
+ }
+
+ dsd = buf.Pointer;
+
+ for (i = 0; i + 1 < dsd->Package.Count; i += 2) {
+ guid = &dsd->Package.Elements[i];
+ package = &dsd->Package.Elements[i + 1];
+
+ if (!cs_is_acpi_guid(guid) ||
+ package->Type != ACPI_TYPE_PACKAGE)
+ break;
+
+ if (!is_acpi_dsd_graph_guid(guid))
+ continue;
+
+ if (cs_acpi_validate_dsd_graph(package))
+ return (package);
+ }
+
+ return (NULL);
+}
+
+static inline bool
+cs_acpi_validate_coresight_graph(const union acpi_object *cs_graph)
+{
+ int nlinks;
+
+ nlinks = cs_graph->Package.Elements[2].Integer.Value;
+ if (cs_graph->Package.Count != (nlinks + 3))
+ return (false);
+
+ return (true);
+}
+
+static const union acpi_object *
+cs_get_coresight_graph(device_t dev)
+{
+ const union acpi_object *graph_list, *graph;
+ int i, nr_graphs;
+
+ graph_list = cs_get_dsd_graph(dev);
+ if (!graph_list) {
+ printf("failed to get graph list\n");
+ return (NULL);
+ }
+
+ nr_graphs = graph_list->Package.Elements[1].Integer.Value;
+ for (i = 2; i < nr_graphs + 2; i++) {
+ graph = &graph_list->Package.Elements[i];
+ if (!cs_is_acpi_coresight_graph(graph))
+ continue;
+ if (cs_acpi_validate_coresight_graph(graph))
+ return (graph);
+ break;
+ }
+
+ return (NULL);
+}
+
+static int
+cs_acpi_record_endpoint(device_t dev,
+ struct coresight_platform_data *pdata,
+ const union acpi_object *link)
+{
+ const union acpi_object *fields;
+ struct endpoint *endp;
+ ACPI_HANDLE handle;
+ int dir;
+
+ if (link->Type != ACPI_TYPE_PACKAGE ||
+ link->Package.Count != 4)
+ return (ENXIO);
+
+ fields = link->Package.Elements;
+ if (fields[0].Type != ACPI_TYPE_INTEGER ||
+ fields[1].Type != ACPI_TYPE_INTEGER ||
+ fields[2].Type != ACPI_TYPE_LOCAL_REFERENCE ||
+ fields[3].Type != ACPI_TYPE_INTEGER)
+ return (ENXIO);
+
+ handle = fields[2].Reference.Handle;
+ dir = fields[3].Integer.Value;
+
+ endp = malloc(sizeof(struct endpoint),
+ M_CORESIGHT, M_WAITOK | M_ZERO);
+ if (endp == NULL) {
+ device_printf(dev, "Failed to allocate memory.\n");
+ return (ENXIO);
+ }
+
+ endp->their_handle = handle;
+ endp->my_handle = acpi_get_handle(dev);
+
+ mtx_lock(&pdata->mtx_lock);
+ TAILQ_INSERT_TAIL(&pdata->endpoints, endp, link);
+ mtx_unlock(&pdata->mtx_lock);
+
+ if (dir == ACPI_CORESIGHT_LINK_OUTPUT) {
+ pdata->out_ports++;
+ } else {
+ endp->input = true;
+ pdata->in_ports++;
+ }
+
+ return (0);
+}
+
+static int
+coresight_acpi_get_ports(device_t dev,
+ struct coresight_platform_data *pdata)
+{
+ const union acpi_object *graph;
+ const union acpi_object *link;
+ int nlinks;
+ int error;
+ int i;
+
+ graph = cs_get_coresight_graph(dev);
+ if (graph == NULL) {
+ device_printf(dev, "Coresight graph not found.\n");
+ return (ENXIO);
+ }
+
+ nlinks = graph->Package.Elements[2].Integer.Value;
+ if (!nlinks)
+ return (0);
+
+ for (i = 0; i < nlinks; i++) {
+ link = &graph->Package.Elements[3 + i];
+ error = cs_acpi_record_endpoint(dev, pdata, link);
+ if (error < 0)
+ return (error);
+ }
+
+ return (0);
+}
+
+static int
+coresight_acpi_get_cpu(device_t dev, struct coresight_platform_data *pdata)
+{
+ ACPI_HANDLE handle, parent;
+ ACPI_STATUS status;
+ int cpuid;
+
+ handle = acpi_get_handle(dev);
+
+ status = AcpiGetParent(handle, &parent);
+ if (!ACPI_SUCCESS(status))
+ return (ENXIO);
+
+ if (!acpi_MatchHid(parent, "ACPI0007"))
+ return (ENXIO);
+
+ status = acpi_GetInteger(parent, "_UID", &cpuid);
+ if (ACPI_SUCCESS(status)) {
+ pdata->cpu = cpuid;
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
+struct coresight_platform_data *
+coresight_acpi_get_platform_data(device_t dev)
+{
+ struct coresight_platform_data *pdata;
+
+ pdata = malloc(sizeof(struct coresight_platform_data),
+ M_CORESIGHT, M_WAITOK | M_ZERO);
+ pdata->bus_type = CORESIGHT_BUS_ACPI;
+
+ mtx_init(&pdata->mtx_lock, "Coresight Platform Data", NULL, MTX_DEF);
+ TAILQ_INIT(&pdata->endpoints);
+
+ coresight_acpi_get_cpu(dev, pdata);
+ coresight_acpi_get_ports(dev, pdata);
+
+ if (bootverbose)
+ printf("Total ports: in %d out %d\n",
+ pdata->in_ports, pdata->out_ports);
+
+ return (pdata);
+}
diff --git a/sys/arm64/coresight/coresight_cmd.c b/sys/arm64/coresight/coresight_cmd.c
index f0e794509009..c25f512f5aa7 100644
--- a/sys/arm64/coresight/coresight_cmd.c
+++ b/sys/arm64/coresight/coresight_cmd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -54,7 +54,7 @@ coresight_next_device(struct coresight_device *cs_dev,
struct endpoint *endp;
TAILQ_FOREACH(endp, &cs_dev->pdata->endpoints, link) {
- if (endp->slave != 0)
+ if (endp->input != 0)
continue;
out = coresight_get_output_device(endp, &out_endp);
@@ -67,6 +67,9 @@ coresight_next_device(struct coresight_device *cs_dev,
}
/* Add output device */
+ if (bootverbose)
+ printf("Adding device %s to the chain\n",
+ device_get_nameunit(out->dev));
out_endp->cs_dev = out;
LIST_INSERT_HEAD(&event->endplist, out_endp, endplink);
diff --git a/sys/arm64/coresight/coresight_cpu_debug.c b/sys/arm64/coresight/coresight_cpu_debug.c
index 42d6cf48d044..c28db5fd51c7 100644
--- a/sys/arm64/coresight/coresight_cpu_debug.c
+++ b/sys/arm64/coresight/coresight_cpu_debug.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -132,7 +132,7 @@ debug_attach(device_t dev)
return (ENXIO);
}
- sc->pdata = coresight_get_platform_data(dev);
+ sc->pdata = coresight_fdt_get_platform_data(dev);
desc.pdata = sc->pdata;
desc.dev = dev;
desc.dev_type = CORESIGHT_CPU_DEBUG;
diff --git a/sys/arm64/coresight/coresight_etm4x.c b/sys/arm64/coresight/coresight_etm4x.c
index d1234b7ae0fa..aabea2c41d99 100644
--- a/sys/arm64/coresight/coresight_etm4x.c
+++ b/sys/arm64/coresight/coresight_etm4x.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -234,7 +234,7 @@ etm_disable(device_t dev, struct endpoint *endp,
} while ((reg & TRCSTATR_IDLE) == 0);
}
-static int
+int
etm_attach(device_t dev)
{
struct coresight_desc desc;
@@ -247,7 +247,6 @@ etm_attach(device_t dev)
return (ENXIO);
}
- sc->pdata = coresight_get_platform_data(dev);
desc.pdata = sc->pdata;
desc.dev = dev;
desc.dev_type = CORESIGHT_ETMV4;
@@ -257,8 +256,6 @@ etm_attach(device_t dev)
}
static device_method_t etm_methods[] = {
- /* Device interface */
- DEVMETHOD(device_attach, etm_attach),
/* Coresight interface */
DEVMETHOD(coresight_init, etm_init),
diff --git a/sys/arm64/coresight/coresight_etm4x.h b/sys/arm64/coresight/coresight_etm4x.h
index 42a4cffedc66..ce84a6c30e70 100644
--- a/sys/arm64/coresight/coresight_etm4x.h
+++ b/sys/arm64/coresight/coresight_etm4x.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -34,13 +34,6 @@
#ifndef _ARM64_CORESIGHT_ETM4X_H_
#define _ARM64_CORESIGHT_ETM4X_H_
-DECLARE_CLASS(etm_driver);
-
-struct etm_softc {
- struct resource *res;
- struct coresight_platform_data *pdata;
-};
-
#define TRCPRGCTLR 0x004 /* Trace Programming Control Register */
#define TRCPRGCTLR_EN (1 << 0) /* Trace unit enable bit */
#define TRCPROCSELR 0x008 /* Trace PE Select Control Register */
@@ -179,4 +172,13 @@ struct etm_softc {
#define TRCPIDR567(n) (0xFD4 + ((n) - 5) * 0x4) /* Management Peripheral ID5 to Peripheral ID7 Registers */
#define TRCCIDR(n) (0xFF0 + (n) * 0x4) /* Management Component IDn Register [n=0-4] */
+DECLARE_CLASS(etm_driver);
+
+struct etm_softc {
+ struct resource *res;
+ struct coresight_platform_data *pdata;
+};
+
+int etm_attach(device_t dev);
+
#endif /* !_ARM64_CORESIGHT_ETM4X_H_ */
diff --git a/sys/arm64/coresight/coresight_etm4x_acpi.c b/sys/arm64/coresight/coresight_etm4x_acpi.c
index 00b29a05a24e..93dfd7a4f880 100644
--- a/sys/arm64/coresight/coresight_etm4x_acpi.c
+++ b/sys/arm64/coresight/coresight_etm4x_acpi.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include
#include
+#include
#include
static int
@@ -62,9 +63,21 @@ etm_acpi_probe(device_t dev)
return (error);
}
+static int
+etm_acpi_attach(device_t dev)
+{
+ struct etm_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_acpi_get_platform_data(dev);
+
+ return (etm_attach(dev));
+}
+
static device_method_t etm_acpi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, etm_acpi_probe),
+ DEVMETHOD(device_attach, etm_acpi_attach),
/* End */
DEVMETHOD_END
diff --git a/sys/arm64/coresight/coresight_etm4x_fdt.c b/sys/arm64/coresight/coresight_etm4x_fdt.c
index a1e5a785ca31..b3418e538a47 100644
--- a/sys/arm64/coresight/coresight_etm4x_fdt.c
+++ b/sys/arm64/coresight/coresight_etm4x_fdt.c
@@ -67,9 +67,21 @@ etm_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+etm_fdt_attach(device_t dev)
+{
+ struct etm_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_fdt_get_platform_data(dev);
+
+ return (etm_attach(dev));
+}
+
static device_method_t etm_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, etm_fdt_probe),
+ DEVMETHOD(device_attach, etm_fdt_attach),
DEVMETHOD_END
};
diff --git a/sys/arm64/coresight/coresight_fdt.c b/sys/arm64/coresight/coresight_fdt.c
new file mode 100644
index 000000000000..cd21b7da706c
--- /dev/null
+++ b/sys/arm64/coresight/coresight_fdt.c
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2018-2020 Ruslan Bukin
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include
+__FBSDID("$FreeBSD$");
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+static int
+coresight_fdt_get_ports(phandle_t dev_node,
+ struct coresight_platform_data *pdata)
+{
+ phandle_t node, child;
+ pcell_t port_reg;
+ phandle_t xref;
+ char *name;
+ int ret;
+ phandle_t endpoint_child;
+ struct endpoint *endp;
+
+ child = ofw_bus_find_child(dev_node, "ports");
+ if (child)
+ node = child;
+ else
+ node = dev_node;
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ ret = OF_getprop_alloc(child, "name", (void **)&name);
+ if (ret == -1)
+ continue;
+
+ if (strcasecmp(name, "port") ||
+ strncasecmp(name, "port@", 6)) {
+
+ port_reg = -1;
+ OF_getencprop(child, "reg", (void *)&port_reg,
+ sizeof(port_reg));
+
+ endpoint_child = ofw_bus_find_child(child, "endpoint");
+ if (endpoint_child) {
+ if (OF_getencprop(endpoint_child,
+ "remote-endpoint", &xref,
+ sizeof(xref)) == -1) {
+ printf("failed\n");
+ continue;
+ }
+ endp = malloc(sizeof(struct endpoint),
+ M_CORESIGHT, M_WAITOK | M_ZERO);
+ endp->my_node = endpoint_child;
+ endp->their_node = OF_node_from_xref(xref);
+ endp->dev_node = dev_node;
+ endp->reg = port_reg;
+ if (OF_getproplen(endpoint_child,
+ "slave-mode") >= 0) {
+ pdata->in_ports++;
+ endp->input = 1;
+ } else
+ pdata->out_ports++;
+
+ mtx_lock(&pdata->mtx_lock);
+ TAILQ_INSERT_TAIL(&pdata->endpoints,
+ endp, link);
+ mtx_unlock(&pdata->mtx_lock);
+ }
+ }
+ }
+
+ return (0);
+}
+
+static int
+coresight_fdt_get_cpu(phandle_t node,
+ struct coresight_platform_data *pdata)
+{
+ phandle_t cpu_node;
+ pcell_t xref;
+ pcell_t cpu_reg;
+
+ if (OF_getencprop(node, "cpu", &xref, sizeof(xref)) != -1) {
+ cpu_node = OF_node_from_xref(xref);
+ if (OF_getencprop(cpu_node, "reg", (void *)&cpu_reg,
+ sizeof(cpu_reg)) > 0) {
+ pdata->cpu = cpu_reg;
+ return (0);
+ }
+ }
+
+ return (-1);
+}
+
+struct coresight_platform_data *
+coresight_fdt_get_platform_data(device_t dev)
+{
+ struct coresight_platform_data *pdata;
+ phandle_t node;
+
+ node = ofw_bus_get_node(dev);
+
+ pdata = malloc(sizeof(struct coresight_platform_data),
+ M_CORESIGHT, M_WAITOK | M_ZERO);
+ pdata->bus_type = CORESIGHT_BUS_FDT;
+
+ mtx_init(&pdata->mtx_lock, "Coresight Platform Data", NULL, MTX_DEF);
+ TAILQ_INIT(&pdata->endpoints);
+
+ coresight_fdt_get_cpu(node, pdata);
+ coresight_fdt_get_ports(node, pdata);
+
+ if (bootverbose)
+ printf("Total ports: in %d out %d\n",
+ pdata->in_ports, pdata->out_ports);
+
+ return (pdata);
+}
diff --git a/sys/arm64/coresight/coresight_funnel.c b/sys/arm64/coresight/coresight_funnel.c
index b183bc247867..2eb588f18366 100644
--- a/sys/arm64/coresight/coresight_funnel.c
+++ b/sys/arm64/coresight/coresight_funnel.c
@@ -111,7 +111,7 @@ funnel_disable(device_t dev, struct endpoint *endp,
bus_write_4(sc->res, FUNNEL_FUNCTL, reg);
}
-static int
+int
funnel_attach(device_t dev)
{
struct coresight_desc desc;
@@ -124,7 +124,6 @@ funnel_attach(device_t dev)
return (ENXIO);
}
- sc->pdata = coresight_get_platform_data(dev);
desc.pdata = sc->pdata;
desc.dev = dev;
desc.dev_type = CORESIGHT_FUNNEL;
@@ -134,9 +133,6 @@ funnel_attach(device_t dev)
}
static device_method_t funnel_methods[] = {
- /* Device interface */
- DEVMETHOD(device_attach, funnel_attach),
-
/* Coresight interface */
DEVMETHOD(coresight_init, funnel_init),
DEVMETHOD(coresight_enable, funnel_enable),
diff --git a/sys/arm64/coresight/coresight_funnel.h b/sys/arm64/coresight/coresight_funnel.h
index 6deab0516715..a064c187b5bb 100644
--- a/sys/arm64/coresight/coresight_funnel.h
+++ b/sys/arm64/coresight/coresight_funnel.h
@@ -75,4 +75,6 @@ struct funnel_softc {
int hwtype;
};
+int funnel_attach(device_t dev);
+
#endif /* !_ARM64_CORESIGHT_CORESIGHT_FUNNEL_H_ */
diff --git a/sys/arm64/coresight/coresight_funnel_acpi.c b/sys/arm64/coresight/coresight_funnel_acpi.c
index 571c771531c4..0757af3d1ce0 100644
--- a/sys/arm64/coresight/coresight_funnel_acpi.c
+++ b/sys/arm64/coresight/coresight_funnel_acpi.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include
#include
+#include
#include
static int
@@ -78,9 +79,21 @@ funnel_acpi_probe(device_t dev)
return (ENXIO);
}
+static int
+funnel_acpi_attach(device_t dev)
+{
+ struct funnel_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_acpi_get_platform_data(dev);
+
+ return (funnel_attach(dev));
+}
+
static device_method_t funnel_acpi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, funnel_acpi_probe),
+ DEVMETHOD(device_attach, funnel_acpi_attach),
/* End */
DEVMETHOD_END
diff --git a/sys/arm64/coresight/coresight_funnel_fdt.c b/sys/arm64/coresight/coresight_funnel_fdt.c
index 6d8514e4fd28..92951e7b3ec9 100644
--- a/sys/arm64/coresight/coresight_funnel_fdt.c
+++ b/sys/arm64/coresight/coresight_funnel_fdt.c
@@ -79,6 +79,17 @@ funnel_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+funnel_fdt_attach(device_t dev)
+{
+ struct funnel_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_fdt_get_platform_data(dev);
+
+ return (funnel_attach(dev));
+}
+
static device_method_t funnel_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, funnel_fdt_probe),
diff --git a/sys/arm64/coresight/coresight_replicator.c b/sys/arm64/coresight/coresight_replicator.c
index 121eb5d10c15..e7b4fdb770f6 100644
--- a/sys/arm64/coresight/coresight_replicator.c
+++ b/sys/arm64/coresight/coresight_replicator.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -95,7 +95,7 @@ replicator_disable(device_t dev, struct endpoint *endp,
bus_write_4(sc->res, REPLICATOR_IDFILTER1, 0xff);
}
-static int
+int
replicator_attach(device_t dev)
{
struct replicator_softc *sc;
@@ -108,7 +108,6 @@ replicator_attach(device_t dev)
return (ENXIO);
}
- sc->pdata = coresight_get_platform_data(dev);
desc.pdata = sc->pdata;
desc.dev = dev;
desc.dev_type = CORESIGHT_DYNAMIC_REPLICATOR;
@@ -118,9 +117,6 @@ replicator_attach(device_t dev)
}
static device_method_t replicator_methods[] = {
- /* Device interface */
- DEVMETHOD(device_attach, replicator_attach),
-
/* Coresight interface */
DEVMETHOD(coresight_init, replicator_init),
DEVMETHOD(coresight_enable, replicator_enable),
diff --git a/sys/arm64/coresight/coresight_replicator.h b/sys/arm64/coresight/coresight_replicator.h
index 62c5c329799c..0b47eb5c9cd7 100644
--- a/sys/arm64/coresight/coresight_replicator.h
+++ b/sys/arm64/coresight/coresight_replicator.h
@@ -43,4 +43,6 @@ struct replicator_softc {
struct coresight_platform_data *pdata;
};
+int replicator_attach(device_t dev);
+
#endif /* !_ARM64_CORESIGHT_CORESIGHT_REPLICATOR_H_ */
diff --git a/sys/arm64/coresight/coresight_replicator_acpi.c b/sys/arm64/coresight/coresight_replicator_acpi.c
index 694b9eaa717c..7cc08930c81f 100644
--- a/sys/arm64/coresight/coresight_replicator_acpi.c
+++ b/sys/arm64/coresight/coresight_replicator_acpi.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include
#include
+#include
#include
static int
@@ -63,9 +64,21 @@ replicator_acpi_probe(device_t dev)
return (error);
}
+static int
+replicator_acpi_attach(device_t dev)
+{
+ struct replicator_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_acpi_get_platform_data(dev);
+
+ return (replicator_attach(dev));
+}
+
static device_method_t replicator_acpi_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, replicator_acpi_probe),
+ DEVMETHOD(device_probe, replicator_acpi_probe),
+ DEVMETHOD(device_attach, replicator_acpi_attach),
/* End */
DEVMETHOD_END
diff --git a/sys/arm64/coresight/coresight_replicator_fdt.c b/sys/arm64/coresight/coresight_replicator_fdt.c
index ef5d67a1db6f..8c5bde1974a8 100644
--- a/sys/arm64/coresight/coresight_replicator_fdt.c
+++ b/sys/arm64/coresight/coresight_replicator_fdt.c
@@ -67,6 +67,17 @@ replicator_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+replicator_acpi_attach(device_t dev)
+{
+ struct replicator_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_fdt_get_platform_data(dev);
+
+ return (replicator_attach(dev));
+}
+
static device_method_t replicator_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, replicator_fdt_probe),
diff --git a/sys/arm64/coresight/coresight_tmc.c b/sys/arm64/coresight/coresight_tmc.c
index 901f2ad81dd6..262e70ea4495 100644
--- a/sys/arm64/coresight/coresight_tmc.c
+++ b/sys/arm64/coresight/coresight_tmc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -312,14 +312,13 @@ tmc_read(device_t dev, struct endpoint *endp,
return (0);
}
-static int
+int
tmc_attach(device_t dev)
{
struct coresight_desc desc;
struct tmc_softc *sc;
sc = device_get_softc(dev);
-
sc->dev = dev;
if (bus_alloc_resources(dev, tmc_spec, &sc->res) != 0) {
@@ -327,7 +326,6 @@ tmc_attach(device_t dev)
return (ENXIO);
}
- sc->pdata = coresight_get_platform_data(dev);
desc.pdata = sc->pdata;
desc.dev = dev;
desc.dev_type = CORESIGHT_TMC;
diff --git a/sys/arm64/coresight/coresight_tmc.h b/sys/arm64/coresight/coresight_tmc.h
index 709f7000d5f1..051fb63f58f9 100644
--- a/sys/arm64/coresight/coresight_tmc.h
+++ b/sys/arm64/coresight/coresight_tmc.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2018 Ruslan Bukin
+ * Copyright (c) 2018-2020 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -132,4 +132,6 @@ struct tmc_softc {
boolean_t etf_configured;
};
+int tmc_attach(device_t dev);
+
#endif /* !_ARM64_CORESIGHT_CORESIGHT_TMC_H_ */
diff --git a/sys/arm64/coresight/coresight_tmc_acpi.c b/sys/arm64/coresight/coresight_tmc_acpi.c
index 33da280008c3..020306593fc8 100644
--- a/sys/arm64/coresight/coresight_tmc_acpi.c
+++ b/sys/arm64/coresight/coresight_tmc_acpi.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include
#include
+#include
#include
static int
@@ -62,9 +63,21 @@ tmc_acpi_probe(device_t dev)
return (error);
}
+static int
+tmc_acpi_attach(device_t dev)
+{
+ struct tmc_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_acpi_get_platform_data(dev);
+
+ return (tmc_attach(dev));
+}
+
static device_method_t tmc_acpi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, tmc_acpi_probe),
+ DEVMETHOD(device_attach, tmc_acpi_attach),
/* End */
DEVMETHOD_END
diff --git a/sys/arm64/coresight/coresight_tmc_fdt.c b/sys/arm64/coresight/coresight_tmc_fdt.c
index 249c817c485d..6b057231e208 100644
--- a/sys/arm64/coresight/coresight_tmc_fdt.c
+++ b/sys/arm64/coresight/coresight_tmc_fdt.c
@@ -67,9 +67,21 @@ tmc_fdt_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
+static int
+tmc_fdt_attach(device_t dev)
+{
+ struct tmc_softc *sc;
+
+ sc = device_get_softc(dev);
+ sc->pdata = coresight_fdt_get_platform_data(dev);
+
+ return (tmc_attach(dev));
+}
+
static device_method_t tmc_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, tmc_fdt_probe),
+ DEVMETHOD(device_attach, tmc_fdt_attach),
DEVMETHOD_END
};
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 1db70147cc74..08addf0df919 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -186,6 +186,8 @@ arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci
arm64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32
arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64
arm64/coresight/coresight.c standard
+arm64/coresight/coresight_acpi.c optional acpi
+arm64/coresight/coresight_fdt.c optional fdt
arm64/coresight/coresight_if.m standard
arm64/coresight/coresight_cmd.c standard
arm64/coresight/coresight_cpu_debug.c standard