Annotation of sys/arch/sparc64/dev/central.c, Revision 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