1*c9ea007cSRuslan Bukin /*-
2*c9ea007cSRuslan Bukin * SPDX-License-Identifier: BSD-2-Clause
3*c9ea007cSRuslan Bukin *
4*c9ea007cSRuslan Bukin * Copyright (c) 2020 Ruslan Bukin <br@bsdpad.com>
5*c9ea007cSRuslan Bukin *
6*c9ea007cSRuslan Bukin * This software was developed by SRI International and the University of
7*c9ea007cSRuslan Bukin * Cambridge Computer Laboratory (Department of Computer Science and
8*c9ea007cSRuslan Bukin * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
9*c9ea007cSRuslan Bukin * DARPA SSITH research programme.
10*c9ea007cSRuslan Bukin *
11*c9ea007cSRuslan Bukin * Redistribution and use in source and binary forms, with or without
12*c9ea007cSRuslan Bukin * modification, are permitted provided that the following conditions
13*c9ea007cSRuslan Bukin * are met:
14*c9ea007cSRuslan Bukin * 1. Redistributions of source code must retain the above copyright
15*c9ea007cSRuslan Bukin * notice, this list of conditions and the following disclaimer.
16*c9ea007cSRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright
17*c9ea007cSRuslan Bukin * notice, this list of conditions and the following disclaimer in the
18*c9ea007cSRuslan Bukin * documentation and/or other materials provided with the distribution.
19*c9ea007cSRuslan Bukin *
20*c9ea007cSRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21*c9ea007cSRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*c9ea007cSRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*c9ea007cSRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24*c9ea007cSRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*c9ea007cSRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*c9ea007cSRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*c9ea007cSRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*c9ea007cSRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*c9ea007cSRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*c9ea007cSRuslan Bukin * SUCH DAMAGE.
31*c9ea007cSRuslan Bukin */
32*c9ea007cSRuslan Bukin
33*c9ea007cSRuslan Bukin #include <sys/param.h>
34*c9ea007cSRuslan Bukin #include <sys/systm.h>
35*c9ea007cSRuslan Bukin #include <sys/bus.h>
36*c9ea007cSRuslan Bukin #include <sys/rman.h>
37*c9ea007cSRuslan Bukin #include <sys/kernel.h>
38*c9ea007cSRuslan Bukin #include <sys/lock.h>
39*c9ea007cSRuslan Bukin #include <sys/module.h>
40*c9ea007cSRuslan Bukin #include <sys/mutex.h>
41*c9ea007cSRuslan Bukin #include <sys/uuid.h>
42*c9ea007cSRuslan Bukin #include <machine/bus.h>
43*c9ea007cSRuslan Bukin
44*c9ea007cSRuslan Bukin #include <contrib/dev/acpica/include/acpi.h>
45*c9ea007cSRuslan Bukin #include <dev/acpica/acpivar.h>
46*c9ea007cSRuslan Bukin
47*c9ea007cSRuslan Bukin #include <arm64/coresight/coresight.h>
48*c9ea007cSRuslan Bukin
49*c9ea007cSRuslan Bukin #define ACPI_CORESIGHT_LINK_OUTPUT 1
50*c9ea007cSRuslan Bukin #define ACPI_CORESIGHT_LINK_INPUT 0
51*c9ea007cSRuslan Bukin
52*c9ea007cSRuslan Bukin static const struct uuid acpi_graph_uuid = {
53*c9ea007cSRuslan Bukin 0xab02a46b, 0x74c7, 0x45a2, 0xbd, 0x68,
54*c9ea007cSRuslan Bukin { 0xf7, 0xd3, 0x44, 0xef, 0x21, 0x53 },
55*c9ea007cSRuslan Bukin };
56*c9ea007cSRuslan Bukin
57*c9ea007cSRuslan Bukin static const struct uuid coresight_graph_uuid = {
58*c9ea007cSRuslan Bukin 0x3ecbc8b6, 0x1d0e, 0x4fb3, 0x81, 0x07,
59*c9ea007cSRuslan Bukin { 0xe6, 0x27, 0xf8, 0x05, 0xc6, 0xcd },
60*c9ea007cSRuslan Bukin };
61*c9ea007cSRuslan Bukin
62*c9ea007cSRuslan Bukin static inline bool
cs_acpi_validate_dsd_graph(const union acpi_object * graph)63*c9ea007cSRuslan Bukin cs_acpi_validate_dsd_graph(const union acpi_object *graph)
64*c9ea007cSRuslan Bukin {
65*c9ea007cSRuslan Bukin const union acpi_object *rev, *nr_graphs;
66*c9ea007cSRuslan Bukin const union acpi_object *obj;
67*c9ea007cSRuslan Bukin int i, n;
68*c9ea007cSRuslan Bukin
69*c9ea007cSRuslan Bukin if (graph->Package.Count < 2)
70*c9ea007cSRuslan Bukin return (false);
71*c9ea007cSRuslan Bukin
72*c9ea007cSRuslan Bukin rev = &graph->Package.Elements[0];
73*c9ea007cSRuslan Bukin nr_graphs = &graph->Package.Elements[1];
74*c9ea007cSRuslan Bukin
75*c9ea007cSRuslan Bukin if (rev->Type != ACPI_TYPE_INTEGER ||
76*c9ea007cSRuslan Bukin nr_graphs->Type != ACPI_TYPE_INTEGER)
77*c9ea007cSRuslan Bukin return (false);
78*c9ea007cSRuslan Bukin
79*c9ea007cSRuslan Bukin /* Revision 0 supported only. */
80*c9ea007cSRuslan Bukin if (rev->Integer.Value != 0)
81*c9ea007cSRuslan Bukin return (false);
82*c9ea007cSRuslan Bukin
83*c9ea007cSRuslan Bukin /* We are looking for a single graph. */
84*c9ea007cSRuslan Bukin n = nr_graphs->Integer.Value;
85*c9ea007cSRuslan Bukin if (n != 1)
86*c9ea007cSRuslan Bukin return (false);
87*c9ea007cSRuslan Bukin
88*c9ea007cSRuslan Bukin /* Check the number of elements. */
89*c9ea007cSRuslan Bukin if (graph->Package.Count != (n + 2))
90*c9ea007cSRuslan Bukin return (false);
91*c9ea007cSRuslan Bukin
92*c9ea007cSRuslan Bukin for (i = 2; i < n + 2; i++) {
93*c9ea007cSRuslan Bukin obj = &graph->Package.Elements[i];
94*c9ea007cSRuslan Bukin if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count < 3)
95*c9ea007cSRuslan Bukin return (false);
96*c9ea007cSRuslan Bukin }
97*c9ea007cSRuslan Bukin
98*c9ea007cSRuslan Bukin return (true);
99*c9ea007cSRuslan Bukin }
100*c9ea007cSRuslan Bukin
101*c9ea007cSRuslan Bukin static inline bool
cs_is_acpi_guid(const union acpi_object * obj)102*c9ea007cSRuslan Bukin cs_is_acpi_guid(const union acpi_object *obj)
103*c9ea007cSRuslan Bukin {
104*c9ea007cSRuslan Bukin
105*c9ea007cSRuslan Bukin return (obj->Type == ACPI_TYPE_BUFFER) && (obj->Buffer.Length == 16);
106*c9ea007cSRuslan Bukin }
107*c9ea007cSRuslan Bukin
108*c9ea007cSRuslan Bukin static inline bool
cs_guid_equal(const struct uuid * u1,const struct uuid * u2)109*c9ea007cSRuslan Bukin cs_guid_equal(const struct uuid *u1, const struct uuid *u2)
110*c9ea007cSRuslan Bukin {
111*c9ea007cSRuslan Bukin
112*c9ea007cSRuslan Bukin if (memcmp(u1, u2, 16) == 0)
113*c9ea007cSRuslan Bukin return (true);
114*c9ea007cSRuslan Bukin
115*c9ea007cSRuslan Bukin return (false);
116*c9ea007cSRuslan Bukin }
117*c9ea007cSRuslan Bukin
118*c9ea007cSRuslan Bukin static inline bool
cs_acpi_guid_matches(const union acpi_object * obj,const struct uuid * guid)119*c9ea007cSRuslan Bukin cs_acpi_guid_matches(const union acpi_object *obj, const struct uuid *guid)
120*c9ea007cSRuslan Bukin {
121*c9ea007cSRuslan Bukin
122*c9ea007cSRuslan Bukin if (cs_is_acpi_guid(obj) &&
123*c9ea007cSRuslan Bukin cs_guid_equal((struct uuid *)obj->Buffer.Pointer, guid))
124*c9ea007cSRuslan Bukin return (true);
125*c9ea007cSRuslan Bukin
126*c9ea007cSRuslan Bukin return (false);
127*c9ea007cSRuslan Bukin }
128*c9ea007cSRuslan Bukin
129*c9ea007cSRuslan Bukin static inline bool
is_acpi_dsd_graph_guid(const union acpi_object * obj)130*c9ea007cSRuslan Bukin is_acpi_dsd_graph_guid(const union acpi_object *obj)
131*c9ea007cSRuslan Bukin {
132*c9ea007cSRuslan Bukin
133*c9ea007cSRuslan Bukin return (cs_acpi_guid_matches(obj, &acpi_graph_uuid));
134*c9ea007cSRuslan Bukin }
135*c9ea007cSRuslan Bukin
136*c9ea007cSRuslan Bukin static inline bool
cs_is_acpi_coresight_graph_guid(const union acpi_object * obj)137*c9ea007cSRuslan Bukin cs_is_acpi_coresight_graph_guid(const union acpi_object *obj)
138*c9ea007cSRuslan Bukin {
139*c9ea007cSRuslan Bukin
140*c9ea007cSRuslan Bukin return (cs_acpi_guid_matches(obj, &coresight_graph_uuid));
141*c9ea007cSRuslan Bukin }
142*c9ea007cSRuslan Bukin
143*c9ea007cSRuslan Bukin static inline bool
cs_is_acpi_coresight_graph(const union acpi_object * obj)144*c9ea007cSRuslan Bukin cs_is_acpi_coresight_graph(const union acpi_object *obj)
145*c9ea007cSRuslan Bukin {
146*c9ea007cSRuslan Bukin const union acpi_object *graphid, *guid, *links;
147*c9ea007cSRuslan Bukin
148*c9ea007cSRuslan Bukin if (obj->Type != ACPI_TYPE_PACKAGE ||
149*c9ea007cSRuslan Bukin obj->Package.Count < 3)
150*c9ea007cSRuslan Bukin return (false);
151*c9ea007cSRuslan Bukin
152*c9ea007cSRuslan Bukin graphid = &obj->Package.Elements[0];
153*c9ea007cSRuslan Bukin guid = &obj->Package.Elements[1];
154*c9ea007cSRuslan Bukin links = &obj->Package.Elements[2];
155*c9ea007cSRuslan Bukin
156*c9ea007cSRuslan Bukin if (graphid->Type != ACPI_TYPE_INTEGER ||
157*c9ea007cSRuslan Bukin links->Type != ACPI_TYPE_INTEGER)
158*c9ea007cSRuslan Bukin return (false);
159*c9ea007cSRuslan Bukin
160*c9ea007cSRuslan Bukin if (cs_is_acpi_coresight_graph_guid(guid))
161*c9ea007cSRuslan Bukin return (true);
162*c9ea007cSRuslan Bukin
163*c9ea007cSRuslan Bukin return (false);
164*c9ea007cSRuslan Bukin }
165*c9ea007cSRuslan Bukin
166*c9ea007cSRuslan Bukin static const union acpi_object *
cs_get_dsd_graph(device_t dev)167*c9ea007cSRuslan Bukin cs_get_dsd_graph(device_t dev)
168*c9ea007cSRuslan Bukin {
169*c9ea007cSRuslan Bukin const union acpi_object *guid, *package;
170*c9ea007cSRuslan Bukin union acpi_object *dsd;
171*c9ea007cSRuslan Bukin ACPI_STATUS status;
172*c9ea007cSRuslan Bukin ACPI_BUFFER buf;
173*c9ea007cSRuslan Bukin device_t bus;
174*c9ea007cSRuslan Bukin int i;
175*c9ea007cSRuslan Bukin
176*c9ea007cSRuslan Bukin buf.Length = PAGE_SIZE;
177*c9ea007cSRuslan Bukin buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO);
178*c9ea007cSRuslan Bukin if (buf.Pointer == NULL) {
179*c9ea007cSRuslan Bukin printf("Failed to allocate memory.\n");
180*c9ea007cSRuslan Bukin return (NULL);
181*c9ea007cSRuslan Bukin }
182*c9ea007cSRuslan Bukin
183*c9ea007cSRuslan Bukin bus = device_get_parent(dev);
184*c9ea007cSRuslan Bukin status = ACPI_EVALUATE_OBJECT(bus, dev, "_DSD", NULL, &buf);
185*c9ea007cSRuslan Bukin if (ACPI_FAILURE(status)) {
186*c9ea007cSRuslan Bukin printf("Failed to evaluate object.\n");
187*c9ea007cSRuslan Bukin return (NULL);
188*c9ea007cSRuslan Bukin }
189*c9ea007cSRuslan Bukin
190*c9ea007cSRuslan Bukin dsd = buf.Pointer;
191*c9ea007cSRuslan Bukin
192*c9ea007cSRuslan Bukin for (i = 0; i + 1 < dsd->Package.Count; i += 2) {
193*c9ea007cSRuslan Bukin guid = &dsd->Package.Elements[i];
194*c9ea007cSRuslan Bukin package = &dsd->Package.Elements[i + 1];
195*c9ea007cSRuslan Bukin
196*c9ea007cSRuslan Bukin if (!cs_is_acpi_guid(guid) ||
197*c9ea007cSRuslan Bukin package->Type != ACPI_TYPE_PACKAGE)
198*c9ea007cSRuslan Bukin break;
199*c9ea007cSRuslan Bukin
200*c9ea007cSRuslan Bukin if (!is_acpi_dsd_graph_guid(guid))
201*c9ea007cSRuslan Bukin continue;
202*c9ea007cSRuslan Bukin
203*c9ea007cSRuslan Bukin if (cs_acpi_validate_dsd_graph(package))
204*c9ea007cSRuslan Bukin return (package);
205*c9ea007cSRuslan Bukin }
206*c9ea007cSRuslan Bukin
207*c9ea007cSRuslan Bukin return (NULL);
208*c9ea007cSRuslan Bukin }
209*c9ea007cSRuslan Bukin
210*c9ea007cSRuslan Bukin static inline bool
cs_acpi_validate_coresight_graph(const union acpi_object * cs_graph)211*c9ea007cSRuslan Bukin cs_acpi_validate_coresight_graph(const union acpi_object *cs_graph)
212*c9ea007cSRuslan Bukin {
213*c9ea007cSRuslan Bukin int nlinks;
214*c9ea007cSRuslan Bukin
215*c9ea007cSRuslan Bukin nlinks = cs_graph->Package.Elements[2].Integer.Value;
216*c9ea007cSRuslan Bukin if (cs_graph->Package.Count != (nlinks + 3))
217*c9ea007cSRuslan Bukin return (false);
218*c9ea007cSRuslan Bukin
219*c9ea007cSRuslan Bukin return (true);
220*c9ea007cSRuslan Bukin }
221*c9ea007cSRuslan Bukin
222*c9ea007cSRuslan Bukin static const union acpi_object *
cs_get_coresight_graph(device_t dev)223*c9ea007cSRuslan Bukin cs_get_coresight_graph(device_t dev)
224*c9ea007cSRuslan Bukin {
225*c9ea007cSRuslan Bukin const union acpi_object *graph_list, *graph;
226*c9ea007cSRuslan Bukin int i, nr_graphs;
227*c9ea007cSRuslan Bukin
228*c9ea007cSRuslan Bukin graph_list = cs_get_dsd_graph(dev);
229*c9ea007cSRuslan Bukin if (!graph_list) {
230*c9ea007cSRuslan Bukin printf("failed to get graph list\n");
231*c9ea007cSRuslan Bukin return (NULL);
232*c9ea007cSRuslan Bukin }
233*c9ea007cSRuslan Bukin
234*c9ea007cSRuslan Bukin nr_graphs = graph_list->Package.Elements[1].Integer.Value;
235*c9ea007cSRuslan Bukin for (i = 2; i < nr_graphs + 2; i++) {
236*c9ea007cSRuslan Bukin graph = &graph_list->Package.Elements[i];
237*c9ea007cSRuslan Bukin if (!cs_is_acpi_coresight_graph(graph))
238*c9ea007cSRuslan Bukin continue;
239*c9ea007cSRuslan Bukin if (cs_acpi_validate_coresight_graph(graph))
240*c9ea007cSRuslan Bukin return (graph);
241*c9ea007cSRuslan Bukin break;
242*c9ea007cSRuslan Bukin }
243*c9ea007cSRuslan Bukin
244*c9ea007cSRuslan Bukin return (NULL);
245*c9ea007cSRuslan Bukin }
246*c9ea007cSRuslan Bukin
247*c9ea007cSRuslan Bukin static int
cs_acpi_record_endpoint(device_t dev,struct coresight_platform_data * pdata,const union acpi_object * link)248*c9ea007cSRuslan Bukin cs_acpi_record_endpoint(device_t dev,
249*c9ea007cSRuslan Bukin struct coresight_platform_data *pdata,
250*c9ea007cSRuslan Bukin const union acpi_object *link)
251*c9ea007cSRuslan Bukin {
252*c9ea007cSRuslan Bukin const union acpi_object *fields;
253*c9ea007cSRuslan Bukin struct endpoint *endp;
254*c9ea007cSRuslan Bukin ACPI_HANDLE handle;
255*c9ea007cSRuslan Bukin int dir;
256*c9ea007cSRuslan Bukin
257*c9ea007cSRuslan Bukin if (link->Type != ACPI_TYPE_PACKAGE ||
258*c9ea007cSRuslan Bukin link->Package.Count != 4)
259*c9ea007cSRuslan Bukin return (ENXIO);
260*c9ea007cSRuslan Bukin
261*c9ea007cSRuslan Bukin fields = link->Package.Elements;
262*c9ea007cSRuslan Bukin if (fields[0].Type != ACPI_TYPE_INTEGER ||
263*c9ea007cSRuslan Bukin fields[1].Type != ACPI_TYPE_INTEGER ||
264*c9ea007cSRuslan Bukin fields[2].Type != ACPI_TYPE_LOCAL_REFERENCE ||
265*c9ea007cSRuslan Bukin fields[3].Type != ACPI_TYPE_INTEGER)
266*c9ea007cSRuslan Bukin return (ENXIO);
267*c9ea007cSRuslan Bukin
268*c9ea007cSRuslan Bukin handle = fields[2].Reference.Handle;
269*c9ea007cSRuslan Bukin dir = fields[3].Integer.Value;
270*c9ea007cSRuslan Bukin
271*c9ea007cSRuslan Bukin endp = malloc(sizeof(struct endpoint),
272*c9ea007cSRuslan Bukin M_CORESIGHT, M_WAITOK | M_ZERO);
273*c9ea007cSRuslan Bukin if (endp == NULL) {
274*c9ea007cSRuslan Bukin device_printf(dev, "Failed to allocate memory.\n");
275*c9ea007cSRuslan Bukin return (ENXIO);
276*c9ea007cSRuslan Bukin }
277*c9ea007cSRuslan Bukin
278*c9ea007cSRuslan Bukin endp->their_handle = handle;
279*c9ea007cSRuslan Bukin endp->my_handle = acpi_get_handle(dev);
280*c9ea007cSRuslan Bukin
281*c9ea007cSRuslan Bukin mtx_lock(&pdata->mtx_lock);
282*c9ea007cSRuslan Bukin TAILQ_INSERT_TAIL(&pdata->endpoints, endp, link);
283*c9ea007cSRuslan Bukin mtx_unlock(&pdata->mtx_lock);
284*c9ea007cSRuslan Bukin
285*c9ea007cSRuslan Bukin if (dir == ACPI_CORESIGHT_LINK_OUTPUT) {
286*c9ea007cSRuslan Bukin pdata->out_ports++;
287*c9ea007cSRuslan Bukin } else {
288*c9ea007cSRuslan Bukin endp->input = true;
289*c9ea007cSRuslan Bukin pdata->in_ports++;
290*c9ea007cSRuslan Bukin }
291*c9ea007cSRuslan Bukin
292*c9ea007cSRuslan Bukin return (0);
293*c9ea007cSRuslan Bukin }
294*c9ea007cSRuslan Bukin
295*c9ea007cSRuslan Bukin static int
coresight_acpi_get_ports(device_t dev,struct coresight_platform_data * pdata)296*c9ea007cSRuslan Bukin coresight_acpi_get_ports(device_t dev,
297*c9ea007cSRuslan Bukin struct coresight_platform_data *pdata)
298*c9ea007cSRuslan Bukin {
299*c9ea007cSRuslan Bukin const union acpi_object *graph;
300*c9ea007cSRuslan Bukin const union acpi_object *link;
301*c9ea007cSRuslan Bukin int nlinks;
302*c9ea007cSRuslan Bukin int error;
303*c9ea007cSRuslan Bukin int i;
304*c9ea007cSRuslan Bukin
305*c9ea007cSRuslan Bukin graph = cs_get_coresight_graph(dev);
306*c9ea007cSRuslan Bukin if (graph == NULL) {
307*c9ea007cSRuslan Bukin device_printf(dev, "Coresight graph not found.\n");
308*c9ea007cSRuslan Bukin return (ENXIO);
309*c9ea007cSRuslan Bukin }
310*c9ea007cSRuslan Bukin
311*c9ea007cSRuslan Bukin nlinks = graph->Package.Elements[2].Integer.Value;
312*c9ea007cSRuslan Bukin if (!nlinks)
313*c9ea007cSRuslan Bukin return (0);
314*c9ea007cSRuslan Bukin
315*c9ea007cSRuslan Bukin for (i = 0; i < nlinks; i++) {
316*c9ea007cSRuslan Bukin link = &graph->Package.Elements[3 + i];
317*c9ea007cSRuslan Bukin error = cs_acpi_record_endpoint(dev, pdata, link);
318*c9ea007cSRuslan Bukin if (error < 0)
319*c9ea007cSRuslan Bukin return (error);
320*c9ea007cSRuslan Bukin }
321*c9ea007cSRuslan Bukin
322*c9ea007cSRuslan Bukin return (0);
323*c9ea007cSRuslan Bukin }
324*c9ea007cSRuslan Bukin
325*c9ea007cSRuslan Bukin static int
coresight_acpi_get_cpu(device_t dev,struct coresight_platform_data * pdata)326*c9ea007cSRuslan Bukin coresight_acpi_get_cpu(device_t dev, struct coresight_platform_data *pdata)
327*c9ea007cSRuslan Bukin {
328*c9ea007cSRuslan Bukin ACPI_HANDLE handle, parent;
329*c9ea007cSRuslan Bukin ACPI_STATUS status;
330*c9ea007cSRuslan Bukin int cpuid;
331*c9ea007cSRuslan Bukin
332*c9ea007cSRuslan Bukin handle = acpi_get_handle(dev);
333*c9ea007cSRuslan Bukin
334*c9ea007cSRuslan Bukin status = AcpiGetParent(handle, &parent);
335*c9ea007cSRuslan Bukin if (!ACPI_SUCCESS(status))
336*c9ea007cSRuslan Bukin return (ENXIO);
337*c9ea007cSRuslan Bukin
338*c9ea007cSRuslan Bukin if (!acpi_MatchHid(parent, "ACPI0007"))
339*c9ea007cSRuslan Bukin return (ENXIO);
340*c9ea007cSRuslan Bukin
341*c9ea007cSRuslan Bukin status = acpi_GetInteger(parent, "_UID", &cpuid);
342*c9ea007cSRuslan Bukin if (ACPI_SUCCESS(status)) {
343*c9ea007cSRuslan Bukin pdata->cpu = cpuid;
344*c9ea007cSRuslan Bukin return (0);
345*c9ea007cSRuslan Bukin }
346*c9ea007cSRuslan Bukin
347*c9ea007cSRuslan Bukin return (ENXIO);
348*c9ea007cSRuslan Bukin }
349*c9ea007cSRuslan Bukin
350*c9ea007cSRuslan Bukin struct coresight_platform_data *
coresight_acpi_get_platform_data(device_t dev)351*c9ea007cSRuslan Bukin coresight_acpi_get_platform_data(device_t dev)
352*c9ea007cSRuslan Bukin {
353*c9ea007cSRuslan Bukin struct coresight_platform_data *pdata;
354*c9ea007cSRuslan Bukin
355*c9ea007cSRuslan Bukin pdata = malloc(sizeof(struct coresight_platform_data),
356*c9ea007cSRuslan Bukin M_CORESIGHT, M_WAITOK | M_ZERO);
357*c9ea007cSRuslan Bukin pdata->bus_type = CORESIGHT_BUS_ACPI;
358*c9ea007cSRuslan Bukin
359*c9ea007cSRuslan Bukin mtx_init(&pdata->mtx_lock, "Coresight Platform Data", NULL, MTX_DEF);
360*c9ea007cSRuslan Bukin TAILQ_INIT(&pdata->endpoints);
361*c9ea007cSRuslan Bukin
362*c9ea007cSRuslan Bukin coresight_acpi_get_cpu(dev, pdata);
363*c9ea007cSRuslan Bukin coresight_acpi_get_ports(dev, pdata);
364*c9ea007cSRuslan Bukin
365*c9ea007cSRuslan Bukin if (bootverbose)
366*c9ea007cSRuslan Bukin printf("Total ports: in %d out %d\n",
367*c9ea007cSRuslan Bukin pdata->in_ports, pdata->out_ports);
368*c9ea007cSRuslan Bukin
369*c9ea007cSRuslan Bukin return (pdata);
370*c9ea007cSRuslan Bukin }
371