xref: /netbsd/sys/arch/sparc/sparc/cpuunit.c (revision c4a72b64)
1 /*	$NetBSD: cpuunit.c,v 1.6 2002/10/02 16:02:10 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the NetBSD
21  *	Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Autoconfiguration support for Sun4d "cpu units".
41  */
42 
43 #include <sys/param.h>
44 #include <sys/malloc.h>
45 #include <sys/systm.h>
46 #include <sys/device.h>
47 
48 #include <machine/autoconf.h>
49 #include <machine/bus.h>
50 
51 #include <sparc/sparc/cpuunitvar.h>
52 
53 struct cpuunit_softc {
54 	struct device sc_dev;
55 	int sc_node;				/* our OBP node */
56 
57 	bus_space_tag_t sc_st;			/* ours */
58 	bus_space_tag_t sc_bustag;		/* passed on to children */
59 
60 	int sc_device_id;			/* device-id */
61 	int sc_board;				/* board number */
62 };
63 
64 static int cpuunit_match(struct device *, struct cfdata *, void *);
65 static void cpuunit_attach(struct device *, struct device *, void *);
66 
67 CFATTACH_DECL(cpuunit, sizeof(struct cpuunit_softc),
68     cpuunit_match, cpuunit_attach, NULL, NULL);
69 
70 static int cpuunit_print(void *, const char *);
71 
72 static int cpuunit_setup_attach_args(struct cpuunit_softc *, bus_space_tag_t,
73     int, struct cpuunit_attach_args *);
74 static void cpuunit_destroy_attach_args(struct cpuunit_attach_args *);
75 
76 static int
77 cpuunit_match(struct device *parent, struct cfdata *cf, void *aux)
78 {
79 	struct mainbus_attach_args *ma = aux;
80 
81 	if (strcmp(ma->ma_name, "cpu-unit") == 0)
82 		return (1);
83 
84 	return (0);
85 }
86 
87 static void
88 cpuunit_attach(struct device *parent, struct device *self, void *aux)
89 {
90 	struct cpuunit_softc *sc = (void *) self;
91 	struct mainbus_attach_args *ma = aux;
92 	int node, error;
93 
94 	sc->sc_node = ma->ma_node;
95 	sc->sc_st = ma->ma_bustag;
96 
97 	sc->sc_device_id = PROM_getpropint(sc->sc_node, "device-id", -1);
98 	sc->sc_board = PROM_getpropint(sc->sc_node, "board#", -1);
99 
100 	printf(": board #%d, ID %d\n", sc->sc_board, sc->sc_device_id);
101 
102 	/*
103 	 * Initialize the bus space tag we pass on to our children.
104 	 */
105 	sc->sc_bustag = malloc(sizeof(*sc->sc_bustag), M_DEVBUF,
106 	    M_WAITOK|M_ZERO);
107 	sc->sc_bustag->cookie = sc;
108 	sc->sc_bustag->parent = sc->sc_st;
109 	sc->sc_bustag->sparc_bus_map = sc->sc_st->sparc_bus_map;
110 	sc->sc_bustag->sparc_bus_mmap = sc->sc_st->sparc_bus_mmap;
111 
112 	/*
113 	 * Collect address translations from the OBP.
114 	 */
115 	error = PROM_getprop(sc->sc_node, "ranges",
116 	    sizeof(struct openprom_range), &sc->sc_bustag->nranges,
117 	    (void **) &sc->sc_bustag->ranges);
118 	if (error) {
119 		printf("%s: error %d getting \"ranges\" property\n",
120 		    sc->sc_dev.dv_xname, error);
121 		panic("cpuunit_attach");
122 	}
123 
124 	/* Attach the CPU (and possibly bootbus) child nodes. */
125 	for (node = firstchild(sc->sc_node); node != 0;
126 	     node = nextsibling(node)) {
127 		struct cpuunit_attach_args cpua;
128 
129 		if (cpuunit_setup_attach_args(sc, sc->sc_bustag, node, &cpua))
130 			panic("cpuunit_attach: failed to set up attach args");
131 
132 		(void) config_found(&sc->sc_dev, &cpua, cpuunit_print);
133 
134 		cpuunit_destroy_attach_args(&cpua);
135 	}
136 }
137 
138 static int
139 cpuunit_print(void *aux, const char *pnp)
140 {
141 	struct cpuunit_attach_args *cpua = aux;
142 
143 	if (pnp)
144 		printf("%s at %s", cpua->cpua_name, pnp);
145 
146 	return (UNCONF);
147 }
148 
149 static int
150 cpuunit_setup_attach_args(struct cpuunit_softc *sc, bus_space_tag_t bustag,
151     int node, struct cpuunit_attach_args *cpua)
152 {
153 	int n, error;
154 
155 	memset(cpua, 0, sizeof(*cpua));
156 
157 	error = PROM_getprop(node, "name", 1, &n, (void **) &cpua->cpua_name);
158 	if (error)
159 		return (error);
160 	cpua->cpua_name[n] = '\0';
161 
162 	error = PROM_getprop(node, "device_type", 1, &n,
163 	    (void **) &cpua->cpua_type);
164 	if (error) {
165 		free(cpua->cpua_name, M_DEVBUF);
166 		return (error);
167 	}
168 
169 	cpua->cpua_bustag = bustag;
170 	cpua->cpua_node = node;
171 	cpua->cpua_device_id = sc->sc_device_id;
172 
173 	return (0);
174 }
175 
176 static void
177 cpuunit_destroy_attach_args(struct cpuunit_attach_args *cpua)
178 {
179 
180 	if (cpua->cpua_name != NULL)
181 		free(cpua->cpua_name, M_DEVBUF);
182 
183 	if (cpua->cpua_type != NULL)
184 		free(cpua->cpua_type, M_DEVBUF);
185 }
186