1 /* $OpenBSD: mainbus.c,v 1.28 2023/03/08 04:43:07 guenther Exp $ */
2
3 /*
4 * Copyright (c) 1994, 1995 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/device.h>
33 #include <sys/malloc.h>
34
35 #include <machine/autoconf.h>
36 #include <dev/ofw/openfirm.h>
37
38 /* Definition of the mainbus driver. */
39 static int mbmatch(struct device *, void *, void *);
40 static void mbattach(struct device *, struct device *, void *);
41 static int mbprint(void *, const char *);
42
43 const struct cfattach mainbus_ca = {
44 sizeof(struct device), mbmatch, mbattach
45 };
46 struct cfdriver mainbus_cd = {
47 NULL, "mainbus", DV_DULL
48 };
49
50 #define HH_REG_CONF 0x90
51
52 static int
mbmatch(struct device * parent,void * cfdata,void * aux)53 mbmatch(struct device *parent, void *cfdata, void *aux)
54 {
55
56 /*
57 * That one mainbus is always here.
58 */
59 return(1);
60 }
61
62 static void
mbattach(struct device * parent,struct device * self,void * aux)63 mbattach(struct device *parent, struct device *self, void *aux)
64 {
65 struct confargs nca;
66 char name[64], *t = NULL;
67 int reg[4], cpucnt;
68 int node, len, tlen;
69
70 node = OF_peer(0);
71 len = OF_getprop(node, "model", name, sizeof(name));
72 if (len > 1) {
73 name[len] = '\0';
74 tlen = strlen(name)+1;
75 if ((t = malloc(tlen, M_DEVBUF, M_NOWAIT)) != NULL)
76 strlcpy(t, name, tlen);
77
78 }
79
80 len = OF_getprop(node, "compatible", name, sizeof(name));
81 if (len > 1) {
82 name[len] = '\0';
83 /* Old World Macintosh */
84 if ((strncmp(name, "AAPL", 4)) == 0) {
85 size_t plen;
86
87 hw_vendor = "Apple Computer, Inc.";
88 plen = strlen(t) + strlen(name) - 3;
89 if ((hw_prod = malloc(plen, M_DEVBUF, M_NOWAIT)) != NULL) {
90 snprintf(hw_prod, plen, "%s %s", t, name + 5);
91 free(t, M_DEVBUF, tlen);
92 }
93 } else {
94 /* New World Macintosh or Unknown */
95 hw_vendor = "Apple Computer, Inc.";
96 hw_prod = t;
97 }
98 }
99 printf(": model %s\n", hw_prod);
100
101 /*
102 * Try to find and attach all of the CPUs in the machine.
103 */
104
105 cpucnt = 0;
106 ncpusfound = 0;
107 node = OF_finddevice("/cpus");
108 if (node != -1) {
109 for (node = OF_child(node); node != 0; node = OF_peer(node)) {
110 u_int32_t cpunum;
111 int len;
112 len = OF_getprop(node, "reg", &cpunum, sizeof cpunum);
113 if (len == 4 && cpucnt == cpunum) {
114 nca.ca_name = "cpu";
115 nca.ca_reg = reg;
116 reg[0] = cpucnt;
117 config_found(self, &nca, mbprint);
118 ncpusfound++;
119 cpucnt++;
120 }
121 }
122 }
123 if (cpucnt == 0) {
124 nca.ca_name = "cpu";
125 nca.ca_reg = reg;
126 reg[0] = 0;
127 ncpusfound++;
128 config_found(self, &nca, mbprint);
129 }
130
131 /*
132 * Special hack for SMP old world macs which lack /cpus and only have
133 * one cpu node.
134 */
135 node = OF_finddevice("/hammerhead");
136 if (node != -1) {
137 len = OF_getprop(node, "reg", reg, sizeof(reg));
138 if (len >= 2) {
139 u_char *hh_base;
140 int twoway = 0;
141
142 if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) {
143 twoway = in32rb(hh_base + HH_REG_CONF) & 0x02;
144 unmapiodev(hh_base, reg[1]);
145 }
146 if (twoway) {
147 nca.ca_name = "cpu";
148 nca.ca_reg = reg;
149 reg[0] = 1;
150 ncpusfound++;
151 config_found(self, &nca, mbprint);
152 }
153 }
154 }
155
156 for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) {
157 bzero (name, sizeof(name));
158 if (OF_getprop(node, "device_type", name, sizeof(name)) <= 0) {
159 if (OF_getprop(node, "name", name, sizeof(name)) <= 0) {
160 printf ("name not found on node %x\n", node);
161 continue;
162 }
163 }
164 if (strcmp(name, "memory") == 0) {
165 nca.ca_name = "mem";
166 nca.ca_node = node;
167 config_found(self, &nca, mbprint);
168 }
169 if (strcmp(name, "memory-controller") == 0) {
170 nca.ca_name = "memc";
171 nca.ca_node = node;
172 config_found(self, &nca, mbprint);
173 }
174 if (strcmp(name, "pci") == 0) {
175 nca.ca_name = "mpcpcibr";
176 nca.ca_node = node;
177 config_found(self, &nca, mbprint);
178 }
179 if (strcmp(name, "ht") == 0) {
180 nca.ca_name = "ht";
181 nca.ca_node = node;
182 config_found(self, &nca, mbprint);
183 }
184 if (strcmp(name, "smu") == 0) {
185 nca.ca_name = "smu";
186 nca.ca_node = node;
187 config_found(self, &nca, mbprint);
188 }
189 }
190 }
191
192 static int
mbprint(void * aux,const char * pnp)193 mbprint(void *aux, const char *pnp)
194 {
195 struct confargs *ca = aux;
196 if (pnp)
197 printf("%s at %s", ca->ca_name, pnp);
198
199 return (UNCONF);
200 }
201