xref: /openbsd-src/sys/arch/macppc/macppc/mainbus.c (revision 5b133f3f277e80f096764111e64f3a1284acb179)
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