1*ecd207b4Sskrll /* $NetBSD: cpus.c,v 1.8 2023/06/12 12:58:17 skrll Exp $ */
2a840d4dcSjmcneill
3a840d4dcSjmcneill /*-
4a840d4dcSjmcneill * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
5a840d4dcSjmcneill * All rights reserved.
6a840d4dcSjmcneill *
7a840d4dcSjmcneill * Redistribution and use in source and binary forms, with or without
8a840d4dcSjmcneill * modification, are permitted provided that the following conditions
9a840d4dcSjmcneill * are met:
10a840d4dcSjmcneill * 1. Redistributions of source code must retain the above copyright
11a840d4dcSjmcneill * notice, this list of conditions and the following disclaimer.
12a840d4dcSjmcneill * 2. Redistributions in binary form must reproduce the above copyright
13a840d4dcSjmcneill * notice, this list of conditions and the following disclaimer in the
14a840d4dcSjmcneill * documentation and/or other materials provided with the distribution.
15a840d4dcSjmcneill *
16a840d4dcSjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17a840d4dcSjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18a840d4dcSjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19a840d4dcSjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20a840d4dcSjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21a840d4dcSjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22a840d4dcSjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23a840d4dcSjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24a840d4dcSjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25a840d4dcSjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26a840d4dcSjmcneill * SUCH DAMAGE.
27a840d4dcSjmcneill */
28a840d4dcSjmcneill
29a840d4dcSjmcneill #include <sys/cdefs.h>
30*ecd207b4Sskrll __KERNEL_RCSID(0, "$NetBSD: cpus.c,v 1.8 2023/06/12 12:58:17 skrll Exp $");
31a840d4dcSjmcneill
32a840d4dcSjmcneill #include <sys/param.h>
33a840d4dcSjmcneill #include <sys/bus.h>
34a840d4dcSjmcneill #include <sys/device.h>
35a840d4dcSjmcneill #include <sys/intr.h>
36a840d4dcSjmcneill #include <sys/systm.h>
37a840d4dcSjmcneill #include <sys/kernel.h>
38a840d4dcSjmcneill #include <sys/kmem.h>
39a840d4dcSjmcneill
40a840d4dcSjmcneill #include <dev/fdt/fdtvar.h>
41a840d4dcSjmcneill
42a840d4dcSjmcneill static int cpus_match(device_t, cfdata_t, void *);
43a840d4dcSjmcneill static void cpus_attach(device_t, device_t, void *);
44a840d4dcSjmcneill
454b28156aSjmcneill static bool cpus_cpu_enabled(int);
46fa8f1d44Sjmcneill
47a840d4dcSjmcneill CFATTACH_DECL_NEW(cpus, 0, cpus_match, cpus_attach, NULL, NULL);
48a840d4dcSjmcneill
49a840d4dcSjmcneill static int
cpus_match(device_t parent,cfdata_t cf,void * aux)50a840d4dcSjmcneill cpus_match(device_t parent, cfdata_t cf, void *aux)
51a840d4dcSjmcneill {
52a840d4dcSjmcneill struct fdt_attach_args * const faa = aux;
53a840d4dcSjmcneill
54a840d4dcSjmcneill return OF_finddevice("/cpus") == faa->faa_phandle;
55a840d4dcSjmcneill }
56a840d4dcSjmcneill
57a840d4dcSjmcneill static void
cpus_attach(device_t parent,device_t self,void * aux)58a840d4dcSjmcneill cpus_attach(device_t parent, device_t self, void *aux)
59a840d4dcSjmcneill {
60a840d4dcSjmcneill struct fdt_attach_args * const faa = aux;
61a840d4dcSjmcneill const int phandle = faa->faa_phandle;
624b28156aSjmcneill int child;
63a840d4dcSjmcneill
64a840d4dcSjmcneill aprint_naive("\n");
65a840d4dcSjmcneill aprint_normal("\n");
66a840d4dcSjmcneill
67*ecd207b4Sskrll fdtbus_cpus_md_attach(parent, self, faa);
68*ecd207b4Sskrll
694b28156aSjmcneill for (child = OF_child(phandle); child; child = OF_peer(child)) {
704b28156aSjmcneill if (!cpus_cpu_enabled(child))
714b28156aSjmcneill continue;
724b28156aSjmcneill fdt_add_child(self, child, faa, 0);
734b28156aSjmcneill }
74fa8f1d44Sjmcneill }
75fa8f1d44Sjmcneill
76fa8f1d44Sjmcneill static bool
cpus_cpu_enabled(int child)774b28156aSjmcneill cpus_cpu_enabled(int child)
78fa8f1d44Sjmcneill {
79fa8f1d44Sjmcneill const char *s;
80fa8f1d44Sjmcneill
81fa8f1d44Sjmcneill /* Only match nodes with device_type = "cpu" */
82fa8f1d44Sjmcneill s = fdtbus_get_string(child, "device_type");
83fa8f1d44Sjmcneill if (!s || strcmp(s, "cpu") != 0)
84fa8f1d44Sjmcneill return false;
85fa8f1d44Sjmcneill
86fa8f1d44Sjmcneill /* If status is set, it must be either "okay" or "disabled" */
87fa8f1d44Sjmcneill s = fdtbus_get_string(child, "status");
88fa8f1d44Sjmcneill if (s) {
89fa8f1d44Sjmcneill if (strcmp(s, "okay") == 0)
900c20e392Sskrll return true;
91fa8f1d44Sjmcneill if (strcmp(s, "disabled") == 0)
92fa8f1d44Sjmcneill return of_hasprop(child, "enable-method");
93fa8f1d44Sjmcneill return false;
94fa8f1d44Sjmcneill } else {
95fa8f1d44Sjmcneill return true;
96fa8f1d44Sjmcneill }
97a840d4dcSjmcneill }
98