Date: Wed, 17 Jun 2020 15:54:51 +0000 (UTC) From: Ruslan Bukin <br@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362278 - in head/sys: arm64/coresight conf Message-ID: <202006171554.05HFspLc075936@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: br Date: Wed Jun 17 15:54:51 2020 New Revision: 362278 URL: https://svnweb.freebsd.org/changeset/base/362278 Log: Complete the ACPI support for ARM Coresight: o Parse the ACPI DSD (Device Specific Data) graph property and record device connections. o Split-out FDT support to a separate file. o Get the corresponding (FDT/ACPI) Coresight platform data in the device drivers. Sponsored by: DARPA, AFRL Added: head/sys/arm64/coresight/coresight_acpi.c (contents, props changed) head/sys/arm64/coresight/coresight_fdt.c (contents, props changed) Modified: head/sys/arm64/coresight/coresight.c head/sys/arm64/coresight/coresight.h head/sys/arm64/coresight/coresight_cmd.c head/sys/arm64/coresight/coresight_cpu_debug.c head/sys/arm64/coresight/coresight_etm4x.c head/sys/arm64/coresight/coresight_etm4x.h head/sys/arm64/coresight/coresight_etm4x_acpi.c head/sys/arm64/coresight/coresight_etm4x_fdt.c head/sys/arm64/coresight/coresight_funnel.c head/sys/arm64/coresight/coresight_funnel.h head/sys/arm64/coresight/coresight_funnel_acpi.c head/sys/arm64/coresight/coresight_funnel_fdt.c head/sys/arm64/coresight/coresight_replicator.c head/sys/arm64/coresight/coresight_replicator.h head/sys/arm64/coresight/coresight_replicator_acpi.c head/sys/arm64/coresight/coresight_replicator_fdt.c head/sys/arm64/coresight/coresight_tmc.c head/sys/arm64/coresight/coresight_tmc.h head/sys/arm64/coresight/coresight_tmc_acpi.c head/sys/arm64/coresight/coresight_tmc_fdt.c head/sys/conf/files.arm64 Modified: head/sys/arm64/coresight/coresight.c ============================================================================== --- head/sys/arm64/coresight/coresight.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight.c Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * This software was developed by SRI International and the University of @@ -41,78 +41,11 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <machine/bus.h> -#include <dev/ofw/ofw_bus.h> -#include <dev/ofw/ofw_bus_subr.h> - #include <arm64/coresight/coresight.h> -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_platfor return (NULL); TAILQ_FOREACH(endp, &pdata->endpoints, link) { - if (endp->slave == 0) + if (endp->input == 0) return (endp); } @@ -151,62 +83,36 @@ coresight_get_output_endpoint(struct coresight_platfor 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; } } } 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 Modified: head/sys/arm64/coresight/coresight.h ============================================================================== --- head/sys/arm64/coresight/coresight.h Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight.h Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * This software was developed by SRI International and the University of @@ -33,8 +33,20 @@ #ifndef _ARM64_CORESIGHT_CORESIGHT_H_ #define _ARM64_CORESIGHT_CORESIGHT_H_ +#include "opt_acpi.h" +#include "opt_platform.h" + +#include <sys/bus.h> + +#ifdef FDT #include <dev/ofw/openfirm.h> +#endif +#ifdef DEV_ACPI +#include <contrib/dev/acpica/include/acpi.h> +#include <dev/acpica/acpivar.h> +#endif + #define CORESIGHT_ITCTRL 0xf00 #define CORESIGHT_CLAIMSET 0xfa0 #define CORESIGHT_CLAIMCLR 0xfa4 @@ -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); Added: head/sys/arm64/coresight/coresight_acpi.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm64/coresight/coresight_acpi.c Wed Jun 17 15:54:51 2020 (r362278) @@ -0,0 +1,373 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Ruslan Bukin <br@bsdpad.com> + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/rman.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/uuid.h> +#include <machine/bus.h> + +#include <contrib/dev/acpica/include/acpi.h> +#include <dev/acpica/acpivar.h> + +#include <arm64/coresight/coresight.h> + +#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); +} Modified: head/sys/arm64/coresight/coresight_cmd.c ============================================================================== --- head/sys/arm64/coresight/coresight_cmd.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_cmd.c Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * 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); Modified: head/sys/arm64/coresight/coresight_cpu_debug.c ============================================================================== --- head/sys/arm64/coresight/coresight_cpu_debug.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_cpu_debug.c Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * 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; Modified: head/sys/arm64/coresight/coresight_etm4x.c ============================================================================== --- head/sys/arm64/coresight/coresight_etm4x.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_etm4x.c Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * 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), Modified: head/sys/arm64/coresight/coresight_etm4x.h ============================================================================== --- head/sys/arm64/coresight/coresight_etm4x.h Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_etm4x.h Wed Jun 17 15:54:51 2020 (r362278) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2018 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> * 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 */ @@ -178,5 +171,14 @@ struct etm_softc { #define TRCPIDR(n) (0xFE0 + (n) * 0x4) /* Management Peripheral IDn Register [n=0-3] */ #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_ */ Modified: head/sys/arm64/coresight/coresight_etm4x_acpi.c ============================================================================== --- head/sys/arm64/coresight/coresight_etm4x_acpi.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_etm4x_acpi.c Wed Jun 17 15:54:51 2020 (r362278) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <contrib/dev/acpica/include/acpi.h> #include <dev/acpica/acpivar.h> +#include <arm64/coresight/coresight.h> #include <arm64/coresight/coresight_etm4x.h> 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 Modified: head/sys/arm64/coresight/coresight_etm4x_fdt.c ============================================================================== --- head/sys/arm64/coresight/coresight_etm4x_fdt.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_etm4x_fdt.c Wed Jun 17 15:54:51 2020 (r362278) @@ -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 }; Added: head/sys/arm64/coresight/coresight_fdt.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm64/coresight/coresight_fdt.c Wed Jun 17 15:54:51 2020 (r362278) @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com> + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/rman.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <machine/bus.h> + +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <arm64/coresight/coresight.h> + +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); +} Modified: head/sys/arm64/coresight/coresight_funnel.c ============================================================================== --- head/sys/arm64/coresight/coresight_funnel.c Wed Jun 17 15:27:45 2020 (r362277) +++ head/sys/arm64/coresight/coresight_funnel.c Wed Jun 17 15:54:51 2020 (r362278) @@ -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) } *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202006171554.05HFspLc075936>