Annotation of sys/arch/macppc/macppc/mainbus.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: mainbus.c,v 1.19 2007/04/03 14:48:53 gwk 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: #include <sys/reboot.h>
! 35:
! 36: #include <machine/autoconf.h>
! 37: #include <dev/ofw/openfirm.h>
! 38:
! 39: struct mainbus_softc {
! 40: struct device sc_dv;
! 41: struct bushook sc_bus;
! 42: };
! 43:
! 44: /* Definition of the mainbus driver. */
! 45: static int mbmatch(struct device *, void *, void *);
! 46: static void mbattach(struct device *, struct device *, void *);
! 47: static int mbprint(void *, const char *);
! 48:
! 49: struct cfattach mainbus_ca = {
! 50: sizeof(struct mainbus_softc), mbmatch, mbattach
! 51: };
! 52: struct cfdriver mainbus_cd = {
! 53: NULL, "mainbus", DV_DULL
! 54: };
! 55:
! 56: /* hw.product sysctl see sys/kern/kern_sysctl.c */
! 57: extern char *hw_prod, *hw_ver, *hw_vendor;
! 58:
! 59: #define HH_REG_CONF 0x90
! 60:
! 61: void mb_intr_establish(struct confargs *, int (*)(void *), void *);
! 62: void mb_intr_disestablish(struct confargs *);
! 63: caddr_t mb_cvtaddr(struct confargs *);
! 64: int mb_matchname(struct confargs *, char *);
! 65:
! 66: /*ARGSUSED*/
! 67: static int
! 68: mbmatch(struct device *parent, void *cfdata, void *aux)
! 69: {
! 70:
! 71: /*
! 72: * That one mainbus is always here.
! 73: */
! 74: return(1);
! 75: }
! 76:
! 77: static void
! 78: mbattach(struct device *parent, struct device *self, void *aux)
! 79: {
! 80: struct mainbus_softc *sc = (struct mainbus_softc *)self;
! 81: struct confargs nca;
! 82: char name[64], *t = NULL;
! 83: int reg[4], cpucnt;
! 84: int node, len, slen;
! 85:
! 86: node = OF_peer(0);
! 87: len = OF_getprop(node, "model", name, sizeof(name));
! 88: if (len > 1) {
! 89: name[len] = '\0';
! 90: slen = strlen(name)+1;
! 91: if ((t = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL)
! 92: strlcpy(t, name, slen);
! 93:
! 94: }
! 95:
! 96: len = OF_getprop(node, "compatible", name, sizeof(name));
! 97: if (len > 1) {
! 98: name[len] = '\0';
! 99: /* Old World Macintosh */
! 100: if ((strncmp(name, "AAPL", 4)) == 0) {
! 101: hw_vendor = "Apple Computer, Inc.";
! 102: slen = strlen(t) + strlen(name) - 3;
! 103: if ((hw_prod = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) {
! 104: snprintf(hw_prod, slen, "%s %s", t, name + 5);
! 105: free(t, M_DEVBUF);
! 106: }
! 107: } else {
! 108: /* New World Macintosh or Unknown */
! 109: hw_vendor = "Apple Computer, Inc.";
! 110: hw_prod = t;
! 111: }
! 112: }
! 113: printf(": model %s\n", hw_prod);
! 114:
! 115: sc->sc_bus.bh_dv = (struct device *)sc;
! 116: sc->sc_bus.bh_type = BUS_MAIN;
! 117: sc->sc_bus.bh_intr_establish = mb_intr_establish;
! 118: sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish;
! 119: sc->sc_bus.bh_matchname = mb_matchname;
! 120:
! 121: /*
! 122: * Try to find and attach all of the CPUs in the machine.
! 123: */
! 124:
! 125: cpucnt = 0;
! 126: node = OF_finddevice("/cpus");
! 127: if (node != -1) {
! 128: for (node = OF_child(node); node != 0; node = OF_peer(node)) {
! 129: u_int32_t cpunum;
! 130: int len;
! 131: len = OF_getprop(node, "reg", &cpunum, sizeof cpunum);
! 132: if (len == 4 && cpucnt == cpunum) {
! 133: nca.ca_name = "cpu";
! 134: nca.ca_bus = &sc->sc_bus;
! 135: nca.ca_reg = reg;
! 136: reg[0] = cpucnt;
! 137: config_found(self, &nca, mbprint);
! 138: cpucnt++;
! 139: }
! 140: }
! 141: }
! 142: if (cpucnt == 0) {
! 143: nca.ca_name = "cpu";
! 144: nca.ca_bus = &sc->sc_bus;
! 145: nca.ca_reg = reg;
! 146: reg[0] = 0;
! 147: config_found(self, &nca, mbprint);
! 148: }
! 149:
! 150: /*
! 151: * Special hack for SMP old world macs which lack /cpus and only have
! 152: * one cpu node.
! 153: */
! 154: node = OF_finddevice("/hammerhead");
! 155: if (node != -1) {
! 156: len = OF_getprop(node, "reg", reg, sizeof(reg));
! 157: if (len >= 2) {
! 158: u_char *hh_base;
! 159: int twoway = 0;
! 160:
! 161: if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) {
! 162: twoway = in32rb(hh_base + HH_REG_CONF) & 0x02;
! 163: unmapiodev(hh_base, reg[1]);
! 164: }
! 165: if (twoway) {
! 166: nca.ca_name = "cpu";
! 167: nca.ca_bus = &sc->sc_bus;
! 168: nca.ca_reg = reg;
! 169: reg[0] = 1;
! 170: config_found(self, &nca, mbprint);
! 171: }
! 172: }
! 173: }
! 174:
! 175: for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) {
! 176: bzero (name, sizeof(name));
! 177: if (OF_getprop(node, "device_type", name,
! 178: sizeof(name)) <= 0) {
! 179: if (OF_getprop(node, "name", name,
! 180: sizeof(name)) <= 0)
! 181: printf ("name not found on node %x\n",
! 182: node);
! 183: continue;
! 184: }
! 185: if (strcmp(name, "memory-controller") == 0) {
! 186: nca.ca_name = "memc";
! 187: nca.ca_node = node;
! 188: nca.ca_bus = &sc->sc_bus;
! 189: config_found(self, &nca, mbprint);
! 190: }
! 191: if (strcmp(name, "pci") == 0) {
! 192: nca.ca_name = "mpcpcibr";
! 193: nca.ca_node = node;
! 194: nca.ca_bus = &sc->sc_bus;
! 195: config_found(self, &nca, mbprint);
! 196: }
! 197: if (strcmp(name, "ht") == 0) {
! 198: nca.ca_name = "ht";
! 199: nca.ca_node = node;
! 200: nca.ca_bus = &sc->sc_bus;
! 201: config_found(self, &nca, mbprint);
! 202: }
! 203: if (strcmp(name, "smu") == 0) {
! 204: nca.ca_name = "smu";
! 205: nca.ca_node = node;
! 206: nca.ca_bus = &sc->sc_bus;
! 207: config_found(self, &nca, mbprint);
! 208: }
! 209: }
! 210: }
! 211:
! 212: static int
! 213: mbprint(void *aux, const char *pnp)
! 214: {
! 215: struct confargs *ca = aux;
! 216: if (pnp)
! 217: printf("%s at %s", ca->ca_name, pnp);
! 218:
! 219: return (UNCONF);
! 220: }
! 221:
! 222: void
! 223: mb_intr_establish(struct confargs *ca, int (*handler)(void *), void *val)
! 224: {
! 225: panic("can never mb_intr_establish");
! 226: }
! 227:
! 228: void
! 229: mb_intr_disestablish(struct confargs *ca)
! 230: {
! 231: panic("can never mb_intr_disestablish");
! 232: }
! 233:
! 234: caddr_t
! 235: mb_cvtaddr(struct confargs *ca)
! 236: {
! 237: return (NULL);
! 238: }
! 239:
! 240: int
! 241: mb_matchname(struct confargs *ca, char *name)
! 242: {
! 243: return (strcmp(name, ca->ca_name) == 0);
! 244: }
CVSweb