1b1670691SRuslan Bukin /*-
25637d889SRuslan Bukin * Copyright (c) 2018-2020 Ruslan Bukin <br@bsdpad.com>
3b1670691SRuslan Bukin * All rights reserved.
4b1670691SRuslan Bukin *
5b1670691SRuslan Bukin * This software was developed by BAE Systems, the University of Cambridge
6b1670691SRuslan Bukin * Computer Laboratory, and Memorial University under DARPA/AFRL contract
7b1670691SRuslan Bukin * FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent Computing
8b1670691SRuslan Bukin * (TC) research program.
9b1670691SRuslan Bukin *
10b1670691SRuslan Bukin * Redistribution and use in source and binary forms, with or without
11b1670691SRuslan Bukin * modification, are permitted provided that the following conditions
12b1670691SRuslan Bukin * are met:
13b1670691SRuslan Bukin * 1. Redistributions of source code must retain the above copyright
14b1670691SRuslan Bukin * notice, this list of conditions and the following disclaimer.
15b1670691SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright
16b1670691SRuslan Bukin * notice, this list of conditions and the following disclaimer in the
17b1670691SRuslan Bukin * documentation and/or other materials provided with the distribution.
18b1670691SRuslan Bukin *
19b1670691SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20b1670691SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21b1670691SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22b1670691SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23b1670691SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24b1670691SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25b1670691SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26b1670691SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27b1670691SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28b1670691SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29b1670691SRuslan Bukin * SUCH DAMAGE.
30b1670691SRuslan Bukin */
31b1670691SRuslan Bukin
32b1670691SRuslan Bukin #include <sys/param.h>
33b1670691SRuslan Bukin #include <sys/systm.h>
34b1670691SRuslan Bukin #include <sys/bus.h>
35b1670691SRuslan Bukin #include <sys/rman.h>
36b1670691SRuslan Bukin #include <sys/kernel.h>
37b1670691SRuslan Bukin #include <sys/module.h>
38b1670691SRuslan Bukin #include <machine/bus.h>
39b1670691SRuslan Bukin
40b1670691SRuslan Bukin #include <arm64/coresight/coresight.h>
41b1670691SRuslan Bukin #include <arm64/coresight/coresight_funnel.h>
42b1670691SRuslan Bukin
43b1670691SRuslan Bukin #include "coresight_if.h"
44b1670691SRuslan Bukin
45b1670691SRuslan Bukin #define FUNNEL_DEBUG
46b1670691SRuslan Bukin #undef FUNNEL_DEBUG
47b1670691SRuslan Bukin
48b1670691SRuslan Bukin #ifdef FUNNEL_DEBUG
49b1670691SRuslan Bukin #define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
50b1670691SRuslan Bukin #else
51b1670691SRuslan Bukin #define dprintf(fmt, ...)
52b1670691SRuslan Bukin #endif
53b1670691SRuslan Bukin
54b1670691SRuslan Bukin static struct resource_spec funnel_spec[] = {
55b1670691SRuslan Bukin { SYS_RES_MEMORY, 0, RF_ACTIVE },
56b1670691SRuslan Bukin { -1, 0 }
57b1670691SRuslan Bukin };
58b1670691SRuslan Bukin
59b1670691SRuslan Bukin static int
funnel_init(device_t dev)60b1670691SRuslan Bukin funnel_init(device_t dev)
61b1670691SRuslan Bukin {
62b1670691SRuslan Bukin struct funnel_softc *sc;
63b1670691SRuslan Bukin
64b1670691SRuslan Bukin sc = device_get_softc(dev);
655637d889SRuslan Bukin if (sc->hwtype == HWTYPE_STATIC_FUNNEL)
665637d889SRuslan Bukin return (0);
67b1670691SRuslan Bukin
68b1670691SRuslan Bukin /* Unlock Coresight */
69b1670691SRuslan Bukin bus_write_4(sc->res, CORESIGHT_LAR, CORESIGHT_UNLOCK);
70b1670691SRuslan Bukin dprintf("Device ID: %x\n", bus_read_4(sc->res, FUNNEL_DEVICEID));
71b1670691SRuslan Bukin
72b1670691SRuslan Bukin return (0);
73b1670691SRuslan Bukin }
74b1670691SRuslan Bukin
75b1670691SRuslan Bukin static int
funnel_enable(device_t dev,struct endpoint * endp,struct coresight_event * event)76b1670691SRuslan Bukin funnel_enable(device_t dev, struct endpoint *endp,
77b1670691SRuslan Bukin struct coresight_event *event)
78b1670691SRuslan Bukin {
79b1670691SRuslan Bukin struct funnel_softc *sc;
80b1670691SRuslan Bukin uint32_t reg;
81b1670691SRuslan Bukin
82b1670691SRuslan Bukin sc = device_get_softc(dev);
835637d889SRuslan Bukin if (sc->hwtype == HWTYPE_STATIC_FUNNEL)
845637d889SRuslan Bukin return (0);
85b1670691SRuslan Bukin
86b1670691SRuslan Bukin reg = bus_read_4(sc->res, FUNNEL_FUNCTL);
87b1670691SRuslan Bukin reg &= ~(FUNCTL_HOLDTIME_MASK);
88b1670691SRuslan Bukin reg |= (7 << FUNCTL_HOLDTIME_SHIFT);
89b1670691SRuslan Bukin reg |= (1 << endp->reg);
90b1670691SRuslan Bukin bus_write_4(sc->res, FUNNEL_FUNCTL, reg);
91b1670691SRuslan Bukin
92b1670691SRuslan Bukin return (0);
93b1670691SRuslan Bukin }
94b1670691SRuslan Bukin
95b1670691SRuslan Bukin static void
funnel_disable(device_t dev,struct endpoint * endp,struct coresight_event * event)96b1670691SRuslan Bukin funnel_disable(device_t dev, struct endpoint *endp,
97b1670691SRuslan Bukin struct coresight_event *event)
98b1670691SRuslan Bukin {
99b1670691SRuslan Bukin struct funnel_softc *sc;
100b1670691SRuslan Bukin uint32_t reg;
101b1670691SRuslan Bukin
102b1670691SRuslan Bukin sc = device_get_softc(dev);
1035637d889SRuslan Bukin if (sc->hwtype == HWTYPE_STATIC_FUNNEL)
1045637d889SRuslan Bukin return;
105b1670691SRuslan Bukin
106b1670691SRuslan Bukin reg = bus_read_4(sc->res, FUNNEL_FUNCTL);
107b1670691SRuslan Bukin reg &= ~(1 << endp->reg);
108b1670691SRuslan Bukin bus_write_4(sc->res, FUNNEL_FUNCTL, reg);
109b1670691SRuslan Bukin }
110b1670691SRuslan Bukin
111*c9ea007cSRuslan Bukin int
funnel_attach(device_t dev)112b1670691SRuslan Bukin funnel_attach(device_t dev)
113b1670691SRuslan Bukin {
114b1670691SRuslan Bukin struct coresight_desc desc;
115b1670691SRuslan Bukin struct funnel_softc *sc;
116b1670691SRuslan Bukin
117b1670691SRuslan Bukin sc = device_get_softc(dev);
1185637d889SRuslan Bukin if (sc->hwtype == HWTYPE_FUNNEL &&
1195637d889SRuslan Bukin bus_alloc_resources(dev, funnel_spec, &sc->res) != 0) {
120b1670691SRuslan Bukin device_printf(dev, "cannot allocate resources for device\n");
121b1670691SRuslan Bukin return (ENXIO);
122b1670691SRuslan Bukin }
123b1670691SRuslan Bukin
124b1670691SRuslan Bukin desc.pdata = sc->pdata;
125b1670691SRuslan Bukin desc.dev = dev;
126b1670691SRuslan Bukin desc.dev_type = CORESIGHT_FUNNEL;
127b1670691SRuslan Bukin coresight_register(&desc);
128b1670691SRuslan Bukin
129b1670691SRuslan Bukin return (0);
130b1670691SRuslan Bukin }
131b1670691SRuslan Bukin
132b1670691SRuslan Bukin static device_method_t funnel_methods[] = {
133b1670691SRuslan Bukin /* Coresight interface */
134b1670691SRuslan Bukin DEVMETHOD(coresight_init, funnel_init),
135b1670691SRuslan Bukin DEVMETHOD(coresight_enable, funnel_enable),
136b1670691SRuslan Bukin DEVMETHOD(coresight_disable, funnel_disable),
137b1670691SRuslan Bukin DEVMETHOD_END
138b1670691SRuslan Bukin };
139b1670691SRuslan Bukin
1405637d889SRuslan Bukin DEFINE_CLASS_0(funnel, funnel_driver, funnel_methods,
1415637d889SRuslan Bukin sizeof(struct funnel_softc));
142