Annotation of sys/arch/sparc64/dev/central.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: central.c,v 1.4 2004/09/27 17:28:03 jason Exp $ */
2:
3: /*
4: * Copyright (c) 2004 Jason L. Wright (jason@thought.net)
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26: * POSSIBILITY OF SUCH DAMAGE.
27: */
28:
29: #include <sys/types.h>
30: #include <sys/param.h>
31: #include <sys/systm.h>
32: #include <sys/kernel.h>
33: #include <sys/device.h>
34: #include <sys/conf.h>
35: #include <sys/timeout.h>
36: #include <sys/malloc.h>
37:
38: #include <machine/bus.h>
39: #include <machine/autoconf.h>
40: #include <machine/openfirm.h>
41:
42: #include <sparc64/dev/centralvar.h>
43:
44: struct central_softc {
45: struct device sc_dv;
46: bus_space_tag_t sc_bt;
47: bus_space_tag_t sc_cbt;
48: int sc_node;
49: int sc_nrange;
50: struct central_range *sc_range;
51: };
52:
53: int central_match(struct device *, void *, void *);
54: void central_attach(struct device *, struct device *, void *);
55:
56: int central_print(void *, const char *);
57: int central_get_string(int, char *, char **);
58:
59: bus_space_tag_t central_alloc_bus_tag(struct central_softc *);
60: int _central_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, bus_size_t,
61: int, bus_space_handle_t *);
62:
63: int
64: central_match(parent, match, aux)
65: struct device *parent;
66: void *match, *aux;
67: {
68: struct mainbus_attach_args *ma = aux;
69:
70: if (strcmp(ma->ma_name, "central") == 0)
71: return (1);
72: return (0);
73: }
74:
75: void
76: central_attach(parent, self, aux)
77: struct device *parent, *self;
78: void *aux;
79: {
80: struct central_softc *sc = (struct central_softc *)self;
81: struct mainbus_attach_args *ma = aux;
82: int node0, node;
83:
84: sc->sc_bt = ma->ma_bustag;
85: sc->sc_node = ma->ma_node;
86: sc->sc_cbt = central_alloc_bus_tag(sc);
87:
88: getprop(sc->sc_node, "ranges", sizeof(struct central_range),
89: &sc->sc_nrange, (void **)&sc->sc_range);
90:
91: printf("\n");
92:
93: node0 = firstchild(sc->sc_node);
94: for (node = node0; node; node = nextsibling(node)) {
95: struct central_attach_args ca;
96:
97: bzero(&ca, sizeof(ca));
98: ca.ca_node = node;
99: ca.ca_bustag = sc->sc_cbt;
100: if (central_get_string(ca.ca_node, "name", &ca.ca_name)) {
101: printf("can't fetch name for node 0x%x\n", node);
102: continue;
103: }
104:
105: getprop(node, "reg", sizeof(struct central_reg),
106: &ca.ca_nreg, (void **)&ca.ca_reg);
107:
108: (void)config_found(&sc->sc_dv, (void *)&ca, central_print);
109:
110: if (ca.ca_name != NULL)
111: free(ca.ca_name, M_DEVBUF);
112: }
113: }
114:
115: int
116: central_get_string(int node, char *name, char **buf)
117: {
118: int len;
119:
120: len = getproplen(node, name);
121: if (len < 0)
122: return (len);
123: *buf = (char *)malloc(len + 1, M_DEVBUF, M_NOWAIT);
124: if (*buf == NULL)
125: return (-1);
126:
127: if (len != 0)
128: getpropstringA(node, name, *buf);
129: (*buf)[len] = '\0';
130: return (0);
131: }
132:
133: int
134: central_print(void *args, const char *busname)
135: {
136: struct central_attach_args *ca = args;
137: char *class;
138:
139: if (busname != NULL) {
140: printf("%s at %s", ca->ca_name, busname);
141: class = getpropstring(ca->ca_node, "device_type");
142: if (*class != '\0')
143: printf(" class %s", class);
144: }
145: return (UNCONF);
146: }
147:
148: bus_space_tag_t
149: central_alloc_bus_tag(struct central_softc *sc)
150: {
151: struct sparc_bus_space_tag *bt;
152:
153: bt = malloc(sizeof(*bt), M_DEVBUF, M_NOWAIT);
154: if (bt == NULL)
155: panic("central: couldn't alloc bus tag");
156:
157: bzero(bt, sizeof(*bt));
158: snprintf(bt->name, sizeof(bt->name), "%s", sc->sc_dv.dv_xname);
159: bt->cookie = sc;
160: bt->parent = sc->sc_bt;
161: bt->asi = bt->parent->asi;
162: bt->sasi = bt->parent->sasi;
163: bt->sparc_bus_map = _central_bus_map;
164: /* XXX bt->sparc_bus_mmap = central_bus_mmap; */
165: /* XXX bt->sparc_intr_establish = upa_intr_establish; */
166: return (bt);
167: }
168:
169: int
170: _central_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t addr,
171: bus_size_t size, int flags, bus_space_handle_t *hp)
172: {
173: struct central_softc *sc = t->cookie;
174: int64_t slot = BUS_ADDR_IOSPACE(addr);
175: int64_t offset = BUS_ADDR_PADDR(addr);
176: int i;
177:
178: if (t->parent == NULL || t->parent->sparc_bus_map == NULL) {
179: printf("\ncentral_bus_map: invalid parent");
180: return (EINVAL);
181: }
182:
183: if (flags & BUS_SPACE_MAP_PROMADDRESS)
184: return ((*t->parent->sparc_bus_map)(t, t0, addr,
185: size, flags, hp));
186:
187: for (i = 0; i < sc->sc_nrange; i++) {
188: bus_addr_t paddr;
189:
190: if (sc->sc_range[i].cspace != slot)
191: continue;
192:
193: paddr = offset - sc->sc_range[i].coffset;
194: paddr += sc->sc_range[i].poffset;
195: paddr |= ((bus_addr_t)sc->sc_range[i].pspace << 32);
196:
197: return ((*t->parent->sparc_bus_map)(t->parent, t0, paddr,
198: size, flags, hp));
199: }
200:
201: return (EINVAL);
202: }
203:
204: struct cfattach central_ca = {
205: sizeof(struct central_softc), central_match, central_attach
206: };
207:
208: struct cfdriver central_cd = {
209: NULL, "central", DV_DULL
210: };
CVSweb