static void prep_pci_get_chipset_tag_indirect(pci_chipset_tag_t pc) { pc->pc_conf_v = (void *)pc; pc->pc_attach_hook = genppc_pci_indirect_attach_hook; pc->pc_bus_maxdevs = prep_pci_bus_maxdevs; pc->pc_make_tag = genppc_pci_indirect_make_tag; pc->pc_conf_read = genppc_pci_indirect_conf_read; pc->pc_conf_write = genppc_pci_indirect_conf_write; pc->pc_intr_v = (void *)pc; pc->pc_intr_map = prep_pci_intr_map; pc->pc_intr_string = genppc_pci_intr_string; pc->pc_intr_evcnt = genppc_pci_intr_evcnt; pc->pc_intr_establish = genppc_pci_intr_establish; pc->pc_intr_disestablish = genppc_pci_intr_disestablish; pc->pc_conf_interrupt = genppc_pci_conf_interrupt; pc->pc_decompose_tag = genppc_pci_indirect_decompose_tag; pc->pc_conf_hook = prep_pci_conf_hook; pc->pc_addr = mapiodev(prep_pci_baseaddr, 4); pc->pc_data = mapiodev(prep_pci_basedata, 4); pc->pc_bus = 0; pc->pc_node = 0; pc->pc_memt = 0; pc->pc_iot = 0; }
void memcattach(struct device *parent, struct device *self, void *aux) { struct memc_softc *sc = (struct memc_softc *)self; struct confargs *ca = aux; uint32_t rev, reg[2]; char name[32]; int len; OF_getprop(ca->ca_node, "reg", ®, sizeof(reg)); len = OF_getprop(ca->ca_node, "name", name, sizeof(name)); if (len > 0) name[len] = 0; /* Map the first page in order to access the registers */ if (strcmp(name, "u3") == 0 || strcmp(name, "u4") == 0) sc->sc_baseaddr = mapiodev(reg[1], PAGE_SIZE); else sc->sc_baseaddr = mapiodev(reg[0], PAGE_SIZE); /* Enable the ethernet clock */ memc_enable(sc, UNINORTH_CLK_OFFSET, UNINORTH_ETHERNET_CTL); len = OF_getprop(ca->ca_node, "device-rev", &rev, sizeof(rev)); if (len < 0) rev = 0; printf (": %s rev 0x%x\n", name, rev); memc_attach_children(sc, ca->ca_node); }
void cgeightattach(struct device *parent, struct device *self, void *args) { struct cgeight_softc *sc = (struct cgeight_softc *)self; struct confargs *ca = args; int node = 0; volatile struct bt_regs *bt; int isconsole = 0; /* Map the pfour register. */ SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); if (cputyp == CPU_SUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->ee_diag.eed_console == EED_CONS_P4) isconsole = 1; } /* Map the Brooktree. */ sc->sc_fbc = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol)); sc->sc_phys = ca->ca_ra.ra_reg[0]; /* enable video */ fb_pfour_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 0); fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_hw = sc; /* * Map the overlay and overlay enable planes. */ sc->sc_enable = (volatile u_char *)mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_ENABLE, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_OVERLAY, round_page(sc->sc_sunfb.sf_fbsize)); cgeight_reset(sc, WSDISPLAYIO_MODE_EMUL); printf(": p4, %dx%d", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); fbwscons_init(&sc->sc_sunfb, isconsole); if (isconsole) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &cgeight_accessops, isconsole); }
void pchbattach(struct device *parent, struct device *self, void *aux) { struct pci_attach_args *pa = aux; char devinfo[256]; #if NAGP > 0 struct agpbus_attach_args apa; #endif volatile unsigned char *python; uint32_t v; aprint_normal("\n"); /* * All we do is print out a description. Eventually, we * might want to add code that does something that's * possibly chipset-specific. */ pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); aprint_normal("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo, PCI_REVISION(pa->pa_class)); switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_IBM: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_IBM_82660: ibm82660_print(pa, self); break; case PCI_PRODUCT_IBM_PYTHON: python = mapiodev(0xfeff6000, 0x60); v = 0x88b78e01; /* taken from linux */ out32rb(python+0x30, v); v = in32rb(python+0x30); aprint_debug("Reset python reg 30 to 0x%x\n", v); break; } break; case PCI_VENDOR_MOT: switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_MOT_MPC105: mpc105_print(pa, self); break; case PCI_PRODUCT_MOT_MPC106: mpc106_print(pa, self); break; } break; } #if NAGP > 0 if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, NULL, NULL) != 0) { apa.apa_pci_args = *pa; config_found_ia(self, "agpbus", &apa, agpbusprint); } #endif /* NAGP */ }
void ki2c_attach(struct device *parent, struct device *self, void *aux) { struct ki2c_softc *sc = (struct ki2c_softc *)self; struct confargs *ca = aux; int node = ca->ca_node; int rate, count = 0; char name[32]; ca->ca_reg[0] += ca->ca_baseaddr; if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) { printf(": cannot get i2c-rate\n"); return; } if (OF_getprop(node, "AAPL,address", &sc->sc_paddr, 4) != 4) { printf(": unable to find i2c address\n"); return; } if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) { printf(": unable to find i2c address step\n"); return; } sc->sc_reg = mapiodev(sc->sc_paddr, (DATA+1)*sc->sc_regstep); printf("\n"); ki2c_writereg(sc, STATUS, 0); ki2c_writereg(sc, ISR, 0); ki2c_writereg(sc, IER, 0); ki2c_setmode(sc, I2C_STDSUBMODE, 0); ki2c_setspeed(sc, I2C_100kHz); /* XXX rate */ lockinit(&sc->sc_buslock, PZERO, sc->sc_dev.dv_xname, 0, 0); ki2c_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP); for (node = OF_child(ca->ca_node); node; node = OF_peer(node)) { if (OF_getprop(node, "name", &name, sizeof name) > 0) { if (strcmp(name, "i2c-bus") == 0) { ki2c_attach_bus(sc, &sc->sc_bus[count], node); if (++count >= KI2C_MAX_BUSSES) break; } } } /* * If we didn't find any i2c-bus nodes, there is only a single * i2c bus. */ if (count == 0) ki2c_attach_bus(sc, &sc->sc_bus[0], ca->ca_node); }
void pmppc_pci_get_chipset_tag(pci_chipset_tag_t pc) { pc->pc_conf_v = (void *)pc; pc->pc_attach_hook = genppc_pci_indirect_attach_hook; pc->pc_bus_maxdevs = genppc_pci_bus_maxdevs; pc->pc_make_tag = genppc_pci_indirect_make_tag; pc->pc_conf_read = genppc_pci_indirect_conf_read; pc->pc_conf_write = genppc_pci_indirect_conf_write; pc->pc_intr_v = (void *)pc; pc->pc_intr_map = pmppc_pci_intr_map; pc->pc_intr_string = genppc_pci_intr_string; pc->pc_intr_evcnt = genppc_pci_intr_evcnt; pc->pc_intr_establish = genppc_pci_intr_establish; pc->pc_intr_disestablish = genppc_pci_intr_disestablish; pc->pc_intr_setattr = genppc_pci_intr_setattr; pc->pc_conf_interrupt = pmppc_pci_conf_interrupt; pc->pc_decompose_tag = genppc_pci_indirect_decompose_tag; pc->pc_conf_hook = genppc_pci_conf_hook; pc->pc_addr = mapiodev(CPC_PCICFGADR, 4, false); pc->pc_data = mapiodev(CPC_PCICFGDATA, 4, false); pc->pc_bus = 0; pc->pc_node = 0; pc->pc_memt = 0; pc->pc_iot = 0; /* the following two lines are required because unlike other ports, * we cannot just add PHYS_TO_BUS_MEM/BUS_MEM_TO_PHYS defines to * bus.h, because it would impact other evbppc ports. */ pci_bus_dma_tag._dma_phys_to_bus_mem = phys_to_pci; pci_bus_dma_tag._dma_bus_mem_to_phys = pci_to_phys; }
void uni_n_config(char *name, int handle) { char *baseaddr; int *ctladdr; u_int32_t address; /* sanity test */ if (strcmp (name, "uni-n") == 0 || strcmp (name, "u3") == 0 || strcmp (name, "u4") == 0) { if (OF_getprop(handle, "reg", &address, sizeof address) > 0) { baseaddr = mapiodev(address, NBPG); ctladdr = (void *)(baseaddr + 0x20); *ctladdr |= 0x02; } } }
void gpio_obio_attach(device_t parent, device_t self, void *aux) { struct gpio_softc *sc = device_private(self); struct confargs *ca = aux, ca2; int child; int namelen; int intr[6]; u_int reg[20]; char name[32]; printf("\n"); sc->sc_port = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1], false); ca2.ca_baseaddr = ca->ca_baseaddr; for (child = OF_child(ca->ca_node); child; child = OF_peer(child)) { namelen = OF_getprop(child, "name", name, sizeof(name)); if (namelen < 0) continue; if (namelen >= sizeof(name)) continue; name[namelen] = 0; ca2.ca_name = name; ca2.ca_node = child; ca2.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); ca2.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, sizeof(intr)); if (ca2.ca_nintr == -1) ca2.ca_nintr = OF_getprop(child, "interrupts", intr, sizeof(intr)); ca2.ca_reg = reg; ca2.ca_intr = intr; config_found(self, &ca2, gpio_obio_print); } }
void wdc_obio_attach(struct device *parent, struct device *self, void *aux) { struct wdc_obio_softc *sc = (void *)self; struct confargs *ca = aux; struct channel_softc *chp = &sc->wdc_channel; int intr, error; bus_addr_t cmdbase; sc->sc_use_dma = 0; if (ca->ca_nreg >= 16) sc->sc_use_dma = 1; /* Enable dma */ sc->sc_dmat = ca->ca_dmat; if ((error = bus_dmamap_create(sc->sc_dmat, WDC_DMALIST_MAX * DBDMA_COUNT_MAX, WDC_DMALIST_MAX, DBDMA_COUNT_MAX, NBPG, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { printf(": cannot create dma map, error = %d\n", error); return; } if (ca->ca_nintr >= 4 && ca->ca_nreg >= 8) { intr = ca->ca_intr[0]; printf(" irq %d", intr); } else if (ca->ca_nintr == -1) { intr = WDC_DEFAULT_PIO_IRQ; printf(" irq property not found; using %d", intr); } else { printf(": couldn't get irq property\n"); return; } if (sc->sc_use_dma) printf(": DMA"); printf("\n"); chp->cmd_iot = chp->ctl_iot = ca->ca_iot; chp->_vtbl = &wdc_obio_vtbl; cmdbase = ca->ca_reg[0]; sc->sc_cmdsize = ca->ca_reg[1]; if (bus_space_map(chp->cmd_iot, cmdbase, sc->sc_cmdsize, 0, &chp->cmd_ioh) || bus_space_subregion(chp->cmd_iot, chp->cmd_ioh, /* WDC_AUXREG_OFFSET<<4 */ 0x160, 1, &chp->ctl_ioh)) { printf("%s: couldn't map registers\n", sc->sc_wdcdev.sc_dev.dv_xname); return; } chp->data32iot = chp->cmd_iot; chp->data32ioh = chp->cmd_ioh; sc->sc_ih = mac_intr_establish(parent, intr, IST_LEVEL, IPL_BIO, wdcintr, chp, sc->sc_wdcdev.sc_dev.dv_xname); sc->sc_wdcdev.set_modes = wdc_obio_adjust_timing; if (sc->sc_use_dma) { sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, WDC_DMALIST_MAX + 1); sc->sc_dmacmd = sc->sc_dbdma->d_addr; sc->sc_dmareg = mapiodev(ca->ca_baseaddr + ca->ca_reg[2], sc->sc_dmasize = ca->ca_reg[3]); sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA; sc->sc_wdcdev.DMA_cap = 2; if (strcmp(ca->ca_name, "ata-4") == 0) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_MODE; sc->sc_wdcdev.UDMA_cap = 4; sc->sc_wdcdev.set_modes = wdc_obio_ata4_adjust_timing; } if (strcmp(ca->ca_name, "ata-6") == 0) { sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_MODE; sc->sc_wdcdev.UDMA_cap = 5; sc->sc_wdcdev.set_modes = wdc_obio_ata6_adjust_timing; } } sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16; sc->sc_wdcdev.PIO_cap = 4; sc->wdc_chanptr = chp; sc->sc_wdcdev.channels = &sc->wdc_chanptr; sc->sc_wdcdev.nchannels = 1; sc->sc_wdcdev.dma_arg = sc; sc->sc_wdcdev.dma_init = wdc_obio_dma_init; sc->sc_wdcdev.dma_start = wdc_obio_dma_start; sc->sc_wdcdev.dma_finish = wdc_obio_dma_finish; chp->channel = 0; chp->wdc = &sc->sc_wdcdev; chp->ch_queue = malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT); if (chp->ch_queue == NULL) { printf("%s: can't allocate memory for command queue", sc->sc_wdcdev.sc_dev.dv_xname); return; } wdcattach(chp); sc->sc_wdcdev.set_modes(chp); wdc_print_current_modes(chp); }
void tcxattach(struct device *parent, struct device *self, void *args) { struct tcx_softc *sc = (struct tcx_softc *)self; struct confargs *ca = args; int node, pri; int isconsole = 0; char *nam = NULL; vaddr_t thc_offset; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d: ", pri); node = ca->ca_ra.ra_node; isconsole = node == fbnode; if (ca->ca_ra.ra_nreg < TCX_NREG) { printf("expected %d registers, got %d\n", TCX_NREG, ca->ca_ra.ra_nreg); return; } nam = getpropstring(node, "model"); if (*nam != '\0') printf("%s, ", nam); /* * Copy the register address spaces needed for mmap operation. */ sc->sc_phys[0] = ca->ca_ra.ra_reg[TCX_REG_DFB8]; sc->sc_phys[1] = ca->ca_ra.ra_reg[TCX_REG_DFB24]; /* * Can't trust the PROM range len here, it is only 4 bytes on the * 8-bit model. Not that it matters much anyway since we map in * pages. */ sc->sc_bt = (volatile struct bt_regs *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt); /* * For some reason S24 PROM sets up TEC and THC ranges at the * right addresses (701000 and 301000), while 8 bit TCX doesn't * (and uses 70000 and 30000) - be sure to only compensate on 8 bit * models. */ if (((vaddr_t)ca->ca_ra.ra_reg[TCX_REG_THC].rr_paddr & 0x1000) != 0) thc_offset = 0; else thc_offset = 0x1000; sc->sc_thc = (volatile struct tcx_thc *) mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC], thc_offset, sizeof *sc->sc_thc); /* * Find out frame buffer geometry, so that we know how much * memory to map. */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_dfb8 = mapiodev(&ca->ca_ra.ra_reg[TCX_REG_DFB8], 0, round_page(sc->sc_sunfb.sf_fbsize)); /* * If the frame buffer advertizes itself as the 8 bit model, or * if the PROM ranges are too small, limit ourselves to 8 bit * operations. * * Further code needing to know which capabilities the frame buffer * has will rely on sc_cplane being non-zero if 24 bit operation * is possible. */ if (!node_has_property(node, "tcx-8-bit") && ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_len >= sc->sc_sunfb.sf_fbsize * 4) { sc->sc_cplane = (paddr_t)ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_paddr; } printf("%dx%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height, sc->sc_cplane == 0 ? 8 : 24); /* * Set up mappings for the acceleration code. This may fail. */ tcx_accel_init(sc, ca); /* reset cursor & frame buffer controls */ tcx_reset(sc, 8); /* enable video */ tcx_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_hw = sc; sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_dfb8; fbwscons_init(&sc->sc_sunfb, isconsole); fbwscons_setcolormap(&sc->sc_sunfb, tcx_setcolor); /* * Now plug accelerated console routines, if possible. */ tcx_accel_plug(sc, ca); sc->sc_ih.ih_fun = tcx_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(tcx_prom, sc); } fbwscons_attach(&sc->sc_sunfb, &tcx_accessops, isconsole); }
static void mbattach(struct device *parent, struct device *self, void *aux) { struct mainbus_softc *sc = (struct mainbus_softc *)self; struct confargs nca; char name[64], *t = NULL; int reg[4], cpucnt; int node, len, slen; node = OF_peer(0); len = OF_getprop(node, "model", name, sizeof(name)); if (len > 1) { name[len] = '\0'; slen = strlen(name)+1; if ((t = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) strlcpy(t, name, slen); } len = OF_getprop(node, "compatible", name, sizeof(name)); if (len > 1) { name[len] = '\0'; /* Old World Macintosh */ if ((strncmp(name, "AAPL", 4)) == 0) { hw_vendor = "Apple Computer, Inc."; slen = strlen(t) + strlen(name) - 3; if ((hw_prod = malloc(slen, M_DEVBUF, M_NOWAIT)) != NULL) { snprintf(hw_prod, slen, "%s %s", t, name + 5); free(t, M_DEVBUF); } } else { /* New World Macintosh or Unknown */ hw_vendor = "Apple Computer, Inc."; hw_prod = t; } } printf(": model %s\n", hw_prod); sc->sc_bus.bh_dv = (struct device *)sc; sc->sc_bus.bh_type = BUS_MAIN; sc->sc_bus.bh_intr_establish = mb_intr_establish; sc->sc_bus.bh_intr_disestablish = mb_intr_disestablish; sc->sc_bus.bh_matchname = mb_matchname; /* * Try to find and attach all of the CPUs in the machine. */ cpucnt = 0; node = OF_finddevice("/cpus"); if (node != -1) { for (node = OF_child(node); node != 0; node = OF_peer(node)) { u_int32_t cpunum; int len; len = OF_getprop(node, "reg", &cpunum, sizeof cpunum); if (len == 4 && cpucnt == cpunum) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = cpucnt; config_found(self, &nca, mbprint); cpucnt++; } } } if (cpucnt == 0) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = 0; config_found(self, &nca, mbprint); } /* * Special hack for SMP old world macs which lack /cpus and only have * one cpu node. */ node = OF_finddevice("/hammerhead"); if (node != -1) { len = OF_getprop(node, "reg", reg, sizeof(reg)); if (len >= 2) { u_char *hh_base; int twoway = 0; if ((hh_base = mapiodev(reg[0], reg[1])) != NULL) { twoway = in32rb(hh_base + HH_REG_CONF) & 0x02; unmapiodev(hh_base, reg[1]); } if (twoway) { nca.ca_name = "cpu"; nca.ca_bus = &sc->sc_bus; nca.ca_reg = reg; reg[0] = 1; config_found(self, &nca, mbprint); } } } for (node = OF_child(OF_peer(0)); node; node=OF_peer(node)) { bzero (name, sizeof(name)); if (OF_getprop(node, "device_type", name, sizeof(name)) <= 0) { if (OF_getprop(node, "name", name, sizeof(name)) <= 0) printf ("name not found on node %x\n", node); continue; } if (strcmp(name, "memory") == 0) { nca.ca_name = "mem"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "memory-controller") == 0) { nca.ca_name = "memc"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "pci") == 0) { nca.ca_name = "mpcpcibr"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "ht") == 0) { nca.ca_name = "ht"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } if (strcmp(name, "smu") == 0) { nca.ca_name = "smu"; nca.ca_node = node; nca.ca_bus = &sc->sc_bus; config_found(self, &nca, mbprint); } } }
void cgtwoattach(struct device *parent, struct device *self, void *args) { struct cgtwo_softc *sc = (struct cgtwo_softc *)self; struct confargs *ca = args; int node = 0; int isconsole = 0; if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == EE_CONS_COLOR) isconsole = 1; } /* * When the ROM has mapped in a cgtwo display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. */ sc->sc_phys = ca->ca_ra.ra_reg[0]; /* Apparently, the pixels are 32-bit data space */ sc->sc_phys.rr_iospace = PMAP_VME32; sc->sc_reg = (volatile struct cg2statusreg *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, status.reg), sizeof(struct cg2statusreg)); sc->sc_ppmask = (volatile u_short *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, ppmask.reg), sizeof(u_short)); sc->sc_cmap = (volatile u_short *) mapiodev(ca->ca_ra.ra_reg, CG2_ROPMEM_OFF + offsetof(struct cg2fb, redmap), 3 * CG2_CMSIZE * sizeof(u_short)); /* enable video */ *sc->sc_ppmask = 0xffff; /* enable all color planes... */ cgtwo_burner(sc, 1, 0); /* ... and video signals */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, CG2_PIXMAP_OFF, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgtwo_setcolor); printf(": %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &cgtwo_accessops, isconsole); }
void agtenattach(struct device *parent, struct device *self, void *args) { struct agten_softc *sc = (struct agten_softc *)self; struct confargs *ca = args; struct wsemuldisplaydev_attach_args waa; int node, isconsole; char *nam; sc->sc_sunfb.sf_flags = self->dv_cfdata->cf_flags; node = ca->ca_ra.ra_node; nam = getpropstring(node, "model"); printf(": model %s", nam); isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; /* * Map the various beasts of this card we are interested in. */ sc->sc_physoffset = (off_t)getpropint(node, "i128_fb_physaddr", 0x8000000); sc->sc_i128_fb = mapiodev(ca->ca_ra.ra_reg, sc->sc_physoffset, getpropint(node, "i128_fb_size", 0x400000)); sc->sc_dac = mapiodev(ca->ca_ra.ra_reg, getpropint(node, "p9100_reg_physaddr", 0x10a0000) + 0x200, 0x800 - 0x200); /* * For some reason the agten does not use the canonical name for * properties, but uses an ffb_ prefix; and the linebytes property is * missing. * The following is a specific version of * fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, BUS_SBUS); * using the correct property names. */ #ifdef notyet sc->sc_sunfb.sf_depth = 32; #else sc->sc_sunfb.sf_depth = getpropint(node, "ffb_depth", 8); #endif sc->sc_sunfb.sf_width = getpropint(node, "ffb_width", 1152); sc->sc_sunfb.sf_height = getpropint(node, "ffb_height", 900); sc->sc_sunfb.sf_linebytes = roundup(sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_depth) * sc->sc_sunfb.sf_depth / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; printf(", %dx%d, depth %d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height, sc->sc_sunfb.sf_depth); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_i128_fb; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole); fbwscons_setcolormap(&sc->sc_sunfb, agten_setcolor); agten_stdscreen.capabilities = sc->sc_sunfb.sf_ro.ri_caps; agten_stdscreen.nrows = sc->sc_sunfb.sf_ro.ri_rows; agten_stdscreen.ncols = sc->sc_sunfb.sf_ro.ri_cols; agten_stdscreen.textops = &sc->sc_sunfb.sf_ro.ri_ops; if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, &agten_stdscreen, -1, NULL); } sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev); waa.console = isconsole; waa.scrdata = &agten_screenlist; waa.accessops = &agten_accessops; waa.accesscookie = sc; config_found(self, &waa, wsemuldisplaydevprint); }
void tslot_attach(struct device *parent, struct device *self, void *args) { struct confargs *ca = args; struct tslot_softc *sc = (struct tslot_softc *)self; struct romaux *ra; struct rom_range ranges[TS102_NUM_RANGES], *range; struct tslot_data *td; volatile u_int8_t *regs; int node, nranges, slot, rnum; ra = &ca->ca_ra; node = ra->ra_node; regs = mapiodev(&ra->ra_reg[0], 0, ra->ra_len); /* * Find memory ranges */ nranges = getproplen(node, "ranges") / sizeof(struct rom_range); if (nranges < TS102_NUM_RANGES) { printf(": expected %d memory ranges, got %d\n", TS102_NUM_RANGES, nranges); return; } getprop(node, "ranges", ranges, sizeof ranges); /* * Ranges being relative to this sbus slot, turn them into absolute * addresses. */ for (rnum = 0; rnum < TS102_NUM_RANGES; rnum++) { ranges[rnum].poffset -= TS102_OFFSET_REGISTERS; } sc->sc_ih.ih_fun = tslot_intr; sc->sc_ih.ih_arg = sc; intr_establish(ra->ra_intr[0].int_pri, &sc->sc_ih, -1, self->dv_xname); printf(" pri %d", ra->ra_intr[0].int_pri); printf(": %d slots\n", TS102_NUM_SLOTS); /* * Setup asynchronous event handler */ sc->sc_events = 0; kthread_create_deferred(tslot_create_event_thread, sc); sc->sc_pct = (pcmcia_chipset_tag_t)&tslot_functions; /* * Setup slots */ for (slot = 0; slot < TS102_NUM_SLOTS; slot++) { td = &sc->sc_slot[slot]; for (rnum = 0; rnum < TS102_RANGE_CNT; rnum++) { range = ranges + (slot * TS102_RANGE_CNT + rnum); td->td_rr = ra->ra_reg[0]; td->td_rr.rr_iospace = range->pspace; td->td_rr.rr_paddr = (void *) ((u_int32_t)td->td_rr.rr_paddr + range->poffset); td->td_space[rnum] = (vaddr_t)mapiodev(&td->td_rr, 0, TS102_ARBITRARY_MAP_SIZE); } td->td_parent = sc; td->td_regs = regs + slot * (TS102_REG_CARD_B_INT - TS102_REG_CARD_A_INT); td->td_slot = slot; SET_TAG_LITTLE_ENDIAN(&td->td_rr); tslot_reset(td, TS102_ARBITRARY_MAP_SIZE); } }
static void grackle_attach(device_t parent, device_t self, void *aux) { struct grackle_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; int len, node = ca->ca_node; uint32_t busrange[2]; struct ranges { uint32_t pci_hi, pci_mid, pci_lo; uint32_t host; uint32_t size_hi, size_lo; } ranges[6], *rp = ranges; aprint_normal("\n"); sc->sc_dev = self; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; /* find i/o tag */ len = OF_getprop(node, "ranges", ranges, sizeof(ranges)); if (len == -1) return; while (len >= sizeof(ranges[0])) { if ((rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == OFW_PCI_PHYS_HI_SPACE_IO) { sc->sc_iot.pbs_base = rp->host; sc->sc_iot.pbs_limit = rp->host + rp->size_lo; break; } len -= sizeof(ranges[0]); rp++; } sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_offset = 0; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "grackle io") != 0) panic("Can't init grackle io tag"); sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE; sc->sc_memt.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt, "grackle mem") != 0) panic("Can't init grackle mem tag"); macppc_pci_get_chipset_tag(pc); pc->pc_node = node; pc->pc_addr = mapiodev(GRACKLE_ADDR, 4, false); pc->pc_data = mapiodev(GRACKLE_DATA, 4, false); pc->pc_bus = busrange[0]; pc->pc_conf_read = grackle_conf_read; pc->pc_conf_write = grackle_conf_write; pc->pc_memt = &sc->sc_memt; pc->pc_iot = &sc->sc_iot; memset(&pba, 0, sizeof(pba)); pba.pba_memt = pc->pc_memt; pba.pba_iot = pc->pc_iot; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = pc->pc_bus; pba.pba_bridgetag = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
void presto_attach(struct device *parent, struct device *self, void *args) { struct presto_softc *sc = (struct presto_softc *)self; struct confargs *ca = args; char *model, *submodel; u_int8_t status; /* Get card parameters */ model = getpropstring(ca->ca_ra.ra_node, "model"); if (*model == '\0') submodel = "fictitious"; else { submodel = memchr(model, ',', strlen(model)); if (submodel != NULL) submodel++; else submodel = model; } strncpy(sc->sc_model, submodel, 16); sc->sc_memsize = ca->ca_ra.ra_len; printf(": %s\n%s: %d MB NVRAM, ", model, sc->sc_dev.dv_xname, sc->sc_memsize >> 20); /* Map memory */ sc->sc_mem = (void *)mapiodev(ca->ca_ra.ra_reg, 0, sc->sc_memsize); /* * Clear the ``disconnect battery'' bit. */ *(u_int8_t *)(sc->sc_mem + PSERVE_BATTERYSTATUS) = 0x00; /* * Clear the ``unflushed data'' status. This way, if the card is * reused under SunOS, the system will not try to flush whatever * data the user put in the nvram... */ *(u_int8_t *)(sc->sc_mem + PSERVE_DATASTATUS) = 0x00; /* * Decode battery status */ status = *(u_int8_t *)(sc->sc_mem + PSERVE_BATTERYSTATUS); printf("battery status %x ", status); if (ISSET(status, PSBAT_FAULT)) { printf("(non-working)"); } else if (ISSET(status, PSBAT_CONNECTED)) { if (ISSET(status, PSBAT_CHARGING)) printf("(charging)"); else printf("(ok)"); } else printf("(disabled)"); printf("\n"); #ifdef DEBUG printf("%s: status codes %02.2x, %02.2x, %02.2x, %02.2x\n", sc->sc_dev.dv_xname, *(u_int8_t *)(sc->sc_mem + 0x03), *(u_int8_t *)(sc->sc_mem + 0x07), *(u_int8_t *)(sc->sc_mem + 0x0b), *(u_int8_t *)(sc->sc_mem + 0x0f)); #endif sc->sc_dk.dk_driver = &presto_dk; sc->sc_dk.dk_name = sc->sc_dev.dv_xname; disk_attach(&sc->sc_dk); /* read the disk label immediately */ presto_getdisklabel(sc); }
void cgfourattach(struct device *parent, struct device *self, void *args) { struct cgfour_softc *sc = (struct cgfour_softc *)self; struct confargs *ca = args; int node = 0; volatile struct bt_regs *bt; int isconsole = 0; printf(": p4"); /* Map the pfour register. */ SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); if (cputyp == CPU_SUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT) isconsole = 1; } /* * When the ROM has mapped in a cgfour display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. We only need the video RAM if we are * going to print characters via rconsole. */ sc->sc_phys = ca->ca_ra.ra_reg[0]; /* enable video */ fb_pfour_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 24); /* * XXX should initialize the enable plane, instead of expecting the * PROM to do so for us */ fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); /* * XXX this only maps the color plane, not the overlay or the enable * planes */ sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_COLOR, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgfour_setcolor); printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &cgfour_accessops, isconsole); }
void bmac_attach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct bmac_softc *sc = (void *)self; struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii = &sc->sc_mii; u_char laddr[6]; int nseg, error; timeout_set(&sc->sc_tick_ch, bmac_mii_tick, sc); sc->sc_flags =0; if (strcmp(ca->ca_name, "ethernet") == 0) { sc->sc_flags |= BMAC_BMACPLUS; } ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; ca->ca_reg[4] += ca->ca_baseaddr; sc->sc_regs = (vaddr_t)mapiodev(ca->ca_reg[0], NBPG); bmac_write_reg(sc, INTDISABLE, NoEventsMask); if (OF_getprop(ca->ca_node, "local-mac-address", laddr, 6) == -1 && OF_getprop(ca->ca_node, "mac-address", laddr, 6) == -1) { printf(": cannot get mac-address\n"); return; } bcopy(laddr, sc->arpcom.ac_enaddr, 6); sc->sc_dmat = ca->ca_dmat; sc->sc_txdma = mapiodev(ca->ca_reg[2], 0x100); sc->sc_rxdma = mapiodev(ca->ca_reg[4], 0x100); sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, BMAC_TXBUFS); sc->sc_txcmd = sc->sc_txdbdma->d_addr; sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, BMAC_RXBUFS + 1); sc->sc_rxcmd = sc->sc_rxdbdma->d_addr; error = bus_dmamem_alloc(sc->sc_dmat, BMAC_BUFSZ, PAGE_SIZE, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT); if (error) { printf(": cannot allocate buffers (%d)\n", error); return; } error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, BMAC_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT); if (error) { printf(": cannot map buffers (%d)\n", error); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); return; } error = bus_dmamap_create(sc->sc_dmat, BMAC_BUFSZ, 1, BMAC_BUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap); if (error) { printf(": cannot create buffer dmamap (%d)\n", error); bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, BMAC_BUFSZ); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); return; } error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_txbuf, BMAC_BUFSZ, NULL, BUS_DMA_NOWAIT); if (error) { printf(": cannot load buffers dmamap (%d)\n", error); bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, BMAC_BUFSZ); bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, nseg); return; } sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr; sc->sc_rxbuf = sc->sc_txbuf + BMAC_BUFLEN * BMAC_TXBUFS; sc->sc_rxbuf_pa = sc->sc_txbuf_pa + BMAC_BUFLEN * BMAC_TXBUFS; printf(" irq %d,%d: address %s\n", ca->ca_intr[0], ca->ca_intr[2], ether_sprintf(laddr)); mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, bmac_intr, sc, sc->sc_dev.dv_xname); mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET, bmac_rint, sc, sc->sc_dev.dv_xname); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_ioctl = bmac_ioctl; ifp->if_start = bmac_start; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_watchdog = bmac_watchdog; IFQ_SET_READY(&ifp->if_snd); mii->mii_ifp = ifp; mii->mii_readreg = bmac_mii_readreg; mii->mii_writereg = bmac_mii_writereg; mii->mii_statchg = bmac_mii_statchg; ifmedia_init(&mii->mii_media, 0, bmac_mediachange, bmac_mediastatus); mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); /* Choose a default media. */ if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_10_T, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_10_T); } else ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); bmac_reset_chip(sc); if_attach(ifp); ether_ifattach(ifp); }
void p9000attach(struct device *parent, struct device *self, void *args) { struct p9000_softc *sc = (struct p9000_softc *)self; struct confargs *ca = args; int node, pri, row, isconsole, scr; struct device *btdev; extern struct cfdriver btcham_cd; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d", pri); #ifdef DIAGNOSTIC if (ca->ca_ra.ra_nreg < P9000_NREG) { printf(": expected %d registers, got only %d\n", P9000_NREG, ca->ca_ra.ra_nreg); return; } #endif /* * Find the RAMDAC device. It should have attached before, since it * attaches at obio. If, for some reason, it did not, it's not worth * going any further. * * We rely upon the PROM to properly initialize the RAMDAC in a safe * mode. */ btdev = btcham_cd.cd_ndevs != 0 ? btcham_cd.cd_devs[0] : NULL; if (btdev != NULL) sc->sc_ramdac = ((struct bt445_softc *)btdev)->sc_regs; if (sc->sc_ramdac == NULL) { printf(": bt445 did not attach previously\n"); return; } sc->sc_phys = ca->ca_ra.ra_reg[P9000_REG_VRAM]; sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CTL]), 0, ca->ca_ra.ra_reg[0].rr_len); sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[P9000_REG_CMD]), 0, ca->ca_ra.ra_reg[1].rr_len); node = ca->ca_ra.ra_node; isconsole = node == fbnode; fb_setsize(&sc->sc_sunfb, 8, 640, 480, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(&sc->sc_phys, 0, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; P9000_SELECT_SCR(sc); scr = P9000_READ_CTL(sc, P9000_SYSTEM_CONFIG); printf(": rev %x, %dx%d\n", scr & SCR_ID_MASK, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); /* Disable frame buffer interrupts */ P9000_SELECT_SCR(sc); P9000_WRITE_CTL(sc, P9000_INTERRUPT_ENABLE, IER_MASTER_ENABLE | 0); sc->sc_ih.ih_fun = p9000_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); /* * If the framebuffer width is under 1024x768, we will switch from the * PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, p9000_setcolor); /* * Plug-in accelerated console operations. */ if (sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags != 0) p9000_ras_init(sc); /* enable video */ p9000_burner(sc, 1, 0); if (isconsole) { if (sc->sc_sunfb.sf_width < 1024) row = 0; /* screen has been cleared above */ else row = -1; fbwscons_console_init(&sc->sc_sunfb, row); } fbwscons_attach(&sc->sc_sunfb, &p9000_accessops, isconsole); }
/* * Attach this instance, and then all the sub-devices */ void espattach(device_t parent, device_t self, void *aux) { struct esp_softc *esc = device_private(self); struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; struct confargs *ca = aux; u_int *reg; int sz; /* * Set up glue for MI code early; we use some of it here. */ sc->sc_dev = self; sc->sc_glue = &esp_glue; esc->sc_node = ca->ca_node; esc->sc_pri = ca->ca_intr[0]; aprint_normal(" irq %d", esc->sc_pri); /* * Map my registers in. */ reg = ca->ca_reg; esc->sc_reg = mapiodev(ca->ca_baseaddr + reg[0], reg[1]); esc->sc_dmareg = mapiodev(ca->ca_baseaddr + reg[2], reg[3]); /* Allocate 16-byte aligned DMA command space */ esc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20); /* Other settings */ sc->sc_id = 7; sz = OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, sizeof(int)); if (sz != sizeof(int)) sc->sc_freq = 25000000; /* gimme MHz */ sc->sc_freq /= 1000000; /* esc->sc_dma->sc_esp = esc;*/ /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Set up static configuration info. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2; /* | NCRCFG2_FE */ sc->sc_cfg3 = NCRCFG3_CDB; sc->sc_rev = NCR_VARIANT_NCR53C94; /* * XXX minsync and maxxfer _should_ be set up in MI code, * XXX but it appears to have some dependency on what sort * XXX of DMA we're hooked up to, etc. */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxxfer = 64 * 1024; /* and the interuppts */ intr_establish(esc->sc_pri, IST_EDGE, IPL_BIO, ncr53c9x_intr, sc); /* Reset SCSI bus when halt. */ shutdownhook_establish(esp_shutdownhook, sc); /* Do the common parts of attachment. */ sc->sc_adapter.adapt_minphys = minphys; sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request; ncr53c9x_attach(sc); /* Turn on target selection using the `DMA' method */ sc->sc_features |= NCR_F_DMASELECT; }
/* * Attach a display. We need to notice if it is the console, too. */ static void cgeightattach(struct device *parent, struct device *self, void *aux) { #if defined(SUN4) union obio_attach_args *uoba = aux; struct obio4_attach_args *oba = &uoba->uoba_oba4; struct cgeight_softc *sc = device_private(self); struct fbdevice *fb = &sc->sc_fb; bus_space_handle_t bh; volatile struct bt_regs *bt; int ramsize, i, isconsole; sc->sc_bustag = oba->oba_bustag; sc->sc_paddr = (bus_addr_t)oba->oba_paddr; /* Map the pfour register. */ if (bus_space_map(oba->oba_bustag, oba->oba_paddr, sizeof(uint32_t), BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map pfour register\n", self->dv_xname); return; } fb->fb_pfour = (volatile uint32_t *)bh; fb->fb_driver = &cgeightfbdriver; fb->fb_device = &sc->sc_dev; fb->fb_type.fb_type = FBTYPE_MEMCOLOR; fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK; fb->fb_flags |= FB_PFOUR; ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY; fb->fb_type.fb_depth = 24; fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900); sc->sc_fb.fb_type.fb_cmsize = 256; sc->sc_fb.fb_type.fb_size = ramsize; printf(": cgeight/p4, %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height); isconsole = 0; if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT) isconsole = fb_is_console(0); } #if 0 /* * We don't do any of the console handling here. Instead, * we let the bwtwo driver pick up the overlay plane and * use it instead. Rconsole should have better performance * with the 1-bit depth. * -- Jason R. Thorpe <*****@*****.**> */ /* * When the ROM has mapped in a cgfour display, the address * maps only the video RAM, so in any case we have to map the * registers ourselves. We only need the video RAM if we are * going to print characters via rconsole. */ if (isconsole) { /* XXX this is kind of a waste */ fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg, PFOUR_COLOR_OFF_OVERLAY, ramsize); } #endif /* Map the Brooktree. */ if (bus_space_map(oba->oba_bustag, oba->oba_paddr + PFOUR_COLOR_OFF_CMAP, sizeof(struct fbcontrol), BUS_SPACE_MAP_LINEAR, &bh) != 0) { printf("%s: cannot map control registers\n", self->dv_xname); return; } sc->sc_fbc = (volatile struct fbcontrol *)bh; #if 0 /* XXX thorpej ??? */ /* tell the enable plane to look at the mono image */ memset(ca->ca_ra.ra_vaddr, 0xff, sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height / 8); #endif /* grab initial (current) color map */ bt = &sc->sc_fbc->fbc_dac; bt->bt_addr = 0; for (i = 0; i < 256 * 3 / 4; i++) sc->sc_cmap.cm_chip[i] = bt->bt_cmap; BT_INIT(bt, 0); #if 0 /* see above */ if (isconsole) { printf(" (console)\n"); #if defined(RASTERCONSOLE) && 0 /* XXX been told it doesn't work well. */ fbrcons_init(fb); #endif } else #endif /* 0 */ printf("\n"); /* * Even though we're not using rconsole, we'd still like * to notice if we're the console framebuffer. */ fb_attach(&sc->sc_fb, isconsole); #endif }
/* * Attach a found zs. * * Match slave number to zs unit number, so that misconfiguration will * not set up the keyboard as ttya, etc. */ void zsc_attach(struct device *parent, struct device *self, void *aux) { struct zsc_softc *zsc = (void *)self; struct confargs *ca = aux; struct zsc_attach_args zsc_args; volatile struct zschan *zc; struct xzs_chanstate *xcs; struct zs_chanstate *cs; struct zsdevice *zsd; int zsc_unit, channel; int s, theflags; int node, intr[3][3]; u_int regs[16]; zsc_unit = zsc->zsc_dev.dv_unit; zsd = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1]); node = OF_child(ca->ca_node); /* ch-a */ for (channel = 0; channel < 2; channel++) { if (OF_getprop(node, "AAPL,interrupts", intr[channel], sizeof(intr[0])) == -1 && OF_getprop(node, "interrupts", intr[channel], sizeof(intr[0])) == -1) { printf(": cannot find interrupt property\n"); return; } if (OF_getprop(node, "reg", regs, sizeof(regs)) < 24) { printf(": cannot find reg property\n"); return; } regs[2] += ca->ca_baseaddr; regs[4] += ca->ca_baseaddr; #ifdef ZS_TXDMA zsc->zsc_txdmareg[channel] = mapiodev(regs[2], regs[3]); zsc->zsc_txdmacmd[channel] = dbdma_alloc(sizeof(dbdma_command_t) * 3); memset(zsc->zsc_txdmacmd[channel], 0, sizeof(dbdma_command_t) * 3); dbdma_reset(zsc->zsc_txdmareg[channel]); #endif node = OF_peer(node); /* ch-b */ } printf(": irq %d,%d\n", intr[0][0], intr[1][0]); /* * Initialize software state for each channel. */ for (channel = 0; channel < 2; channel++) { zsc_args.channel = channel; zsc_args.hwflags = zs_hwflags[zsc_unit][channel]; xcs = &zsc->xzsc_xcs_store[channel]; cs = &xcs->xzs_cs; zsc->zsc_cs[channel] = cs; cs->cs_channel = channel; cs->cs_private = NULL; cs->cs_ops = &zsops_null; zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b; cs->cs_reg_csr = &zc->zc_csr; cs->cs_reg_data = &zc->zc_data; memcpy(cs->cs_creg, zs_init_reg, 16); memcpy(cs->cs_preg, zs_init_reg, 16); /* Current BAUD rate generator clock. */ /* RTxC is 230400*16, so use 230400 */ cs->cs_brg_clk = PCLK / 16; if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE) cs->cs_defspeed = zs_get_speed(cs); else cs->cs_defspeed = zs_defspeed[zsc_unit][channel]; cs->cs_defcflag = zs_def_cflag; /* Make these correspond to cs_defcflag (-crtscts) */ cs->cs_rr0_dcd = ZSRR0_DCD; cs->cs_rr0_cts = 0; cs->cs_wr5_dtr = ZSWR5_DTR; cs->cs_wr5_rts = 0; #ifdef __notyet__ cs->cs_slave_type = ZS_SLAVE_NONE; #endif /* Define BAUD rate stuff. */ xcs->cs_clocks[0].clk = PCLK; xcs->cs_clocks[0].flags = ZSC_RTXBRG | ZSC_RTXDIV; xcs->cs_clocks[1].flags = ZSC_RTXBRG | ZSC_RTXDIV | ZSC_VARIABLE | ZSC_EXTERN; xcs->cs_clocks[2].flags = ZSC_TRXDIV | ZSC_VARIABLE; xcs->cs_clock_count = 3; if (channel == 0) { theflags = 0; /*mac68k_machine.modem_flags;*/ /*xcs->cs_clocks[1].clk = mac68k_machine.modem_dcd_clk;*/ /*xcs->cs_clocks[2].clk = mac68k_machine.modem_cts_clk;*/ xcs->cs_clocks[1].clk = 0; xcs->cs_clocks[2].clk = 0; } else { theflags = 0; /*mac68k_machine.print_flags;*/ xcs->cs_clocks[1].flags = ZSC_VARIABLE; /* * Yes, we aren't defining ANY clock source enables for the * printer's DCD clock in. The hardware won't let us * use it. But a clock will freak out the chip, so we * let you set it, telling us to bar interrupts on the line. */ /*xcs->cs_clocks[1].clk = mac68k_machine.print_dcd_clk;*/ /*xcs->cs_clocks[2].clk = mac68k_machine.print_cts_clk;*/ xcs->cs_clocks[1].clk = 0; xcs->cs_clocks[2].clk = 0; } if (xcs->cs_clocks[1].clk) zsc_args.hwflags |= ZS_HWFLAG_NO_DCD; if (xcs->cs_clocks[2].clk) zsc_args.hwflags |= ZS_HWFLAG_NO_CTS; /* Set defaults in our "extended" chanstate. */ xcs->cs_csource = 0; xcs->cs_psource = 0; xcs->cs_cclk_flag = 0; /* Nothing fancy by default */ xcs->cs_pclk_flag = 0; if (theflags & ZSMAC_RAW) { zsc_args.hwflags |= ZS_HWFLAG_RAW; printf(" (raw defaults)"); } /* * XXX - This might be better done with a "stub" driver * (to replace zstty) that ignores LocalTalk for now. */ if (theflags & ZSMAC_LOCALTALK) { printf(" shielding from LocalTalk"); cs->cs_defspeed = 1; cs->cs_creg[ZSRR_BAUDLO] = cs->cs_preg[ZSRR_BAUDLO] = 0xff; cs->cs_creg[ZSRR_BAUDHI] = cs->cs_preg[ZSRR_BAUDHI] = 0xff; zs_write_reg(cs, ZSRR_BAUDLO, 0xff); zs_write_reg(cs, ZSRR_BAUDHI, 0xff); /* * If we might have LocalTalk, then make sure we have the * Baud rate low-enough to not do any damage. */ } /* * We used to disable chip interrupts here, but we now * do that in zscnprobe, just in case MacOS left the chip on. */ xcs->cs_chip = 0; /* Stash away a copy of the final H/W flags. */ xcs->cs_hwflags = zsc_args.hwflags; /* * Look for a child driver for this channel. * The child attach will setup the hardware. */ if (!config_found(self, (void *)&zsc_args, zsc_print)) { /* No sub-driver. Just reset it. */ u_char reset = (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET; s = splzs(); zs_write_reg(cs, 9, reset); splx(s); } } /* XXX - Now safe to install interrupt handlers. */ mac_intr_establish(parent, intr[0][0], IST_LEVEL, IPL_TTY, zshard, NULL, "zs0"); mac_intr_establish(parent, intr[1][0], IST_LEVEL, IPL_TTY, zshard, NULL, "zs1"); #ifdef ZS_TXDMA mac_intr_establish(parent, intr[0][1], IST_LEVEL, IPL_TTY, zs_txdma_int, (void *)0, "zsdma0"); mac_intr_establish(parent, intr[1][1], IST_LEVEL, IPL_TTY, zs_txdma_int, (void *)1, "zsdma1"); #endif zsc->zsc_softintr = softintr_establish(IPL_SOFTTTY, zssoft, zsc); if (zsc->zsc_softintr == NULL) panic("zsattach: could not establish soft interrupt"); /* * Set the master interrupt enable and interrupt vector. * (common to both channels, do it on A) */ cs = zsc->zsc_cs[0]; s = splzs(); /* interrupt vector */ zs_write_reg(cs, 2, zs_init_reg[2]); /* master interrupt control (enable) */ zs_write_reg(cs, 9, zs_init_reg[9]); splx(s); /* connect power management for port 0 */ cs->enable = zs_enable; cs->disable = zs_disable; }
/* * Attach all the sub-devices we can find */ void macobio_attach(struct device *parent, struct device *self, void *aux) { struct macobio_softc *sc = (struct macobio_softc *)self; struct pci_attach_args *pa = aux; struct confargs ca; int node, child, namelen; u_int32_t reg[20]; int32_t intr[8]; char name[32]; int need_interrupt_controller = 0; sc->sc_id = pa->pa_id; /* save of type for later */ switch (PCI_PRODUCT(pa->pa_id)) { /* XXX should not use name */ case PCI_PRODUCT_APPLE_GC: node = OF_finddevice("/bandit/gc"); need_interrupt_controller = 1; break; case PCI_PRODUCT_APPLE_OHARE: node = OF_finddevice("/bandit/ohare"); need_interrupt_controller = 1; break; case PCI_PRODUCT_APPLE_HEATHROW: case PCI_PRODUCT_APPLE_PADDINGTON: node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) == (sizeof (reg[0]) * 5)) { /* always ??? */ heathrow_FCR = mapiodev(reg[2] + HEATHROW_FCR_OFFSET, 4); } break; case PCI_PRODUCT_APPLE_KEYLARGO: case PCI_PRODUCT_APPLE_INTREPID: case PCI_PRODUCT_APPLE_PANGEA_MACIO: case PCI_PRODUCT_APPLE_SHASTA: case PCI_PRODUCT_APPLE_K2_MACIO: node = OF_finddevice("mac-io"); if (node == -1) node = OF_finddevice("/pci/mac-io"); if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) == (sizeof (reg[0]) * 5)) sc->obiomem = mapiodev(reg[2], 0x100); break; default: printf(": unknown macobio controller\n"); return; } sc->sc_node = node; if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12) return; ca.ca_baseaddr = reg[2]; sc->sc_membus_space.bus_base = ca.ca_baseaddr; ca.ca_iot = &sc->sc_membus_space; ca.ca_dmat = pa->pa_dmat; printf("\n"); /* * This might be a hack, but it makes the interrupt controller * attach as expected if a device node existed in the OF tree. */ if (need_interrupt_controller) { /* force attachment of legacy interrupt controllers */ ca.ca_name = "legacy-interrupt-controller"; ca.ca_node = 0; ca.ca_nreg = 0; ca.ca_nintr = 0; ca.ca_reg = NULL; ca.ca_intr = NULL; config_found(self, &ca, macobio_print); } for (child = OF_child(node); child; child = OF_peer(child)) { namelen = OF_getprop(child, "name", name, sizeof(name)); if (namelen < 0) continue; if (namelen >= sizeof(name)) continue; name[namelen] = 0; ca.ca_name = name; ca.ca_node = child; ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg)); ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr, sizeof(intr)); if (ca.ca_nintr == -1) ca.ca_nintr = OF_getprop(child, "interrupts", intr, sizeof(intr)); ca.ca_reg = reg; ca.ca_intr = intr; config_found(self, &ca, macobio_print); } }
void bwtwoattach(struct device *parent, struct device *self, void *args) { struct bwtwo_softc *sc = (struct bwtwo_softc *)self; struct confargs *ca = args; int node = ca->ca_ra.ra_node; int isconsole = 0; int sbus = 1; char *nam; printf(": "); /* * Map the control register. */ #if defined(SUN4) if (CPU_ISSUN4 && ca->ca_bustype == BUS_OBIO && fb_pfour_id(ca->ca_ra.ra_vaddr) != PFOUR_NOTPFOUR) { SET(sc->sc_sunfb.sf_flags, FB_PFOUR); sc->sc_sunfb.sf_pfour = (volatile u_int32_t *) mapiodev(ca->ca_ra.ra_reg, 0, sizeof(u_int32_t)); } else #endif { sc->sc_reg = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, BWREG_REG, sizeof(struct fbcontrol)); } /* Set up default pixel offset. May be changed below. */ sc->sc_pixeloffset = BWREG_MEM; switch (ca->ca_bustype) { case BUS_OBIO: if (CPU_ISSUN4M) /* 4m has framebuffer on obio */ goto obp_name; sbus = node = 0; #if defined(SUN4) if (ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR)) { nam = "p4"; sc->sc_pixeloffset = PFOUR_BW_OFF; } else #endif nam = NULL; break; case BUS_VME32: case BUS_VME16: sbus = node = 0; nam = NULL; break; case BUS_SBUS: obp_name: #if defined(SUN4C) || defined(SUN4M) nam = getpropstring(node, "model"); #endif break; } if (nam != NULL && *nam != '\0') printf("%s, ", nam); #if defined(SUN4) if (CPU_ISSUN4) { struct eeprom *eep = (struct eeprom *)eeprom_va; int constype = ISSET(sc->sc_sunfb.sf_flags, FB_PFOUR) ? EE_CONS_P4OPT : EE_CONS_BW; /* * Assume this is the console if there's no eeprom info * to be found. */ if (eep == NULL || eep->eeConsole == constype) isconsole = 1; else /* * On sun4 systems without on-board framebuffers (such as * the 4/3xx models), the PROM will accept the EE_CONS_BW * setting although the framebuffer is a P4. * Accept this setting as well. */ if (eep->eeConsole == EE_CONS_BW) isconsole = 1; } #endif if (CPU_ISSUN4COR4M) isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; sc->sc_bustype = ca->ca_bustype; /* enable video */ bwtwo_burner(sc, 1, 0); fb_setsize(&sc->sc_sunfb, 1, 1152, 900, node, ca->ca_bustype); printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, sc->sc_pixeloffset, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); } fbwscons_attach(&sc->sc_sunfb, &bwtwo_accessops, isconsole); }
/* * Attach this instance, and then all the sub-devices */ void espattach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct esp_softc *esc = (void *)self; struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; u_int *reg; int sz, error; /* * Set up glue for MI code early; we use some of it here. */ sc->sc_glue = &esp_glue; esc->sc_node = ca->ca_node; esc->sc_intr = ca->ca_intr[0]; printf(" irq %d", esc->sc_intr); /* * Map my registers in. */ reg = ca->ca_reg; esc->sc_reg = mapiodev(ca->ca_baseaddr + reg[0], reg[1]); esc->sc_dmareg = mapiodev(ca->ca_baseaddr + reg[2], reg[3]); esc->sc_dmat = ca->ca_dmat; if ((error = bus_dmamap_create(esc->sc_dmat, ESP_DMALIST_MAX * DBDMA_COUNT_MAX, ESP_DMALIST_MAX, DBDMA_COUNT_MAX, NBPG, BUS_DMA_NOWAIT, &esc->sc_dmamap)) != 0) { printf(": cannot create dma map, error = %d\n", error); return; } /* Allocate 16-byte aligned DMA command space */ esc->sc_dbdma = dbdma_alloc(esc->sc_dmat, ESP_DMALIST_MAX); esc->sc_dmacmd = esc->sc_dbdma->d_addr; /* Other settings */ sc->sc_id = 7; sz = OF_getprop(ca->ca_node, "clock-frequency", &sc->sc_freq, sizeof(int)); if (sz != sizeof(int)) sc->sc_freq = 25000000; /* gimme MHz */ sc->sc_freq /= 1000000; /* * Set up static configuration info. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2; /* | NCRCFG2_FE */ sc->sc_cfg3 = NCRCFG3_CDB; sc->sc_rev = NCR_VARIANT_NCR53C94; /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxxfer = 64 * 1024; /* and the interuppts */ mac_intr_establish(parent, esc->sc_intr, IST_LEVEL, IPL_BIO, ncr53c9x_intr, sc, sc->sc_dev.dv_xname); /* Turn on target selection using the `DMA' method */ sc->sc_features |= NCR_F_DMASELECT; ncr53c9x_attach(sc); }
void mc_attach(struct device *parent, struct device *self, void *aux) { struct confargs *ca = aux; struct mc_softc *sc = (struct mc_softc *)self; struct ifnet *ifp = &sc->sc_arpcom.ac_if; u_int8_t lladdr[ETHER_ADDR_LEN]; int nseg, error; if (OF_getprop(ca->ca_node, "local-mac-address", lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN) { printf(": failed to get MAC address.\n"); return; } ca->ca_reg[0] += ca->ca_baseaddr; ca->ca_reg[2] += ca->ca_baseaddr; ca->ca_reg[4] += ca->ca_baseaddr; if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) { printf(": cannot map registers\n"); return; } sc->sc_dmat = ca->ca_dmat; sc->sc_tail = 0; if ((sc->sc_txdma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) { printf(": cannot map TX DMA registers\n"); goto notxdma; } if ((sc->sc_rxdma = mapiodev(ca->ca_reg[4], ca->ca_reg[5])) == NULL) { printf(": cannot map RX DMA registers\n"); goto norxdma; } if ((sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, 2)) == NULL) { printf(": cannot alloc TX DMA descriptors\n"); goto notxdbdma; } sc->sc_txdmacmd = sc->sc_txdbdma->d_addr; if ((sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, 8 + 1)) == NULL) { printf(": cannot alloc RX DMA descriptors\n"); goto norxdbdma; } sc->sc_rxdmacmd = sc->sc_rxdbdma->d_addr; if ((error = bus_dmamem_alloc(sc->sc_dmat, MACE_BUFSZ, PAGE_SIZE, 0, sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) { printf(": cannot allocate DMA mem (%d)\n", error); goto nodmamem; } if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, MACE_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT))) { printf(": cannot map DMA mem (%d)\n", error); goto nodmamap; } if ((error = bus_dmamap_create(sc->sc_dmat, MACE_BUFSZ, 1, MACE_BUFSZ, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) { printf(": cannot create DMA map (%d)\n", error); goto nodmacreate; } if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_txbuf, MACE_BUFSZ, NULL, BUS_DMA_NOWAIT))) { printf(": cannot load DMA map (%d)\n", error); goto nodmaload; } sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr; sc->sc_rxbuf = sc->sc_txbuf + MACE_BUFLEN * MACE_TXBUFS; sc->sc_rxbuf_pa = sc->sc_txbuf_pa + MACE_BUFLEN * MACE_TXBUFS; printf(": irq %d,%d,%d", ca->ca_intr[0], ca->ca_intr[1], ca->ca_intr[2]); /* disable receive DMA */ dbdma_reset(sc->sc_rxdma); /* disable transmit DMA */ dbdma_reset(sc->sc_txdma); /* install interrupt handlers */ mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET, mc_dmaintr, sc, sc->sc_dev.dv_xname); mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, mc_intr, sc, sc->sc_dev.dv_xname); sc->sc_biucc = XMTSP_64; sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST; sc->sc_plscc = PORTSEL_GPSI | ENPLSIO; /* reset the chip and disable all interrupts */ NIC_PUT(sc, MACE_BIUCC, SWRST); DELAY(100); NIC_PUT(sc, MACE_IMR, ~0); bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN); bcopy(sc->sc_enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); printf(": address %s\n", ether_sprintf(lladdr)); bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_ioctl = mc_ioctl; ifp->if_start = mc_start; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; ifp->if_watchdog = mc_watchdog; ifp->if_timer = 0; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp); return; nodmaload: bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); nodmacreate: bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, MACE_BUFSZ); nodmamap: bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); nodmamem: dbdma_free(sc->sc_rxdbdma); norxdbdma: dbdma_free(sc->sc_txdbdma); notxdbdma: unmapiodev((void *)sc->sc_rxdma, ca->ca_reg[5]); norxdma: unmapiodev((void *)sc->sc_txdma, ca->ca_reg[3]); notxdma: unmapiodev(sc->sc_reg, ca->ca_reg[1]); }
void cgthreeattach(struct device *parent, struct device *self, void *args) { struct cgthree_softc *sc = (struct cgthree_softc *)self; struct confargs *ca = args; int node, pri, isrdi = 0, i; volatile struct bt_regs *bt; int isconsole; char *nam; pri = ca->ca_ra.ra_intr[0].int_pri; printf(" pri %d: ", pri); node = ca->ca_ra.ra_node; if (strcmp(ca->ca_ra.ra_name, "cgRDI") == 0) { isrdi = 1; nam = "cgRDI"; } else nam = getpropstring(node, "model"); if (nam != NULL && *nam != '\0') printf("%s, ", nam); isconsole = node == fbnode; sc->sc_fbc = (volatile struct fbcontrol *) mapiodev(ca->ca_ra.ra_reg, CG3REG_REG, sizeof(struct fbcontrol)); /* Transfer video magic to board, if it's not running */ if (isrdi == 0 && (sc->sc_fbc->fbc_ctrl & FBC_TIMING) == 0) for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]); i++) { volatile struct fbcontrol *fbc = sc->sc_fbc; if (cg3_videoctrl[i].sense == 0xff || (fbc->fbc_status & FBS_MSENSE) == cg3_videoctrl[i].sense) { int j; #ifdef DEBUG printf(" (setting video ctrl)"); #endif for (j = 0; j < 12; j++) fbc->fbc_vcontrol[j] = cg3_videoctrl[i].vctrl[j]; fbc->fbc_ctrl |= FBC_TIMING; break; } } sc->sc_phys = ca->ca_ra.ra_reg[0]; sc->sc_ih.ih_fun = cgthree_intr; sc->sc_ih.ih_arg = sc; intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname); /* enable video */ cgthree_burner(sc, 1, 0); bt = &sc->sc_fbc->fbc_dac; BT_INIT(bt, 0); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, CG3REG_MEM, round_page(sc->sc_sunfb.sf_fbsize)); sc->sc_sunfb.sf_ro.ri_hw = sc; printf("%dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); /* * If the framebuffer width is under 1024x768, which is the case for * some clones on laptops, as well as with the VS10-EK, switch from * the PROM font to the more adequate 8x16 font here. * However, we need to adjust two things in this case: * - the display row should be overrided from the current PROM metrics, * to prevent us from overwriting the last few lines of text. * - if the 80x34 screen would make a large margin appear around it, * choose to clear the screen rather than keeping old prom output in * the margins. * XXX there should be a rasops "clear margins" feature */ fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width >= 1024) ? 0 : RI_CLEAR); fbwscons_setcolormap(&sc->sc_sunfb, cgthree_setcolor); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, sc->sc_sunfb.sf_width >= 1024 ? -1 : 0); } fbwscons_attach(&sc->sc_sunfb, &cgthree_accessops, isconsole); }
static void uninorth_attach(device_t parent, device_t self, void *aux) { struct uninorth_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; int len, child, node = ca->ca_node; uint32_t reg[2], busrange[2]; char compat[32]; int ver; struct ranges { uint32_t pci_hi, pci_mid, pci_lo; uint32_t host; uint32_t size_hi, size_lo; } ranges[6], *rp = ranges; printf("\n"); sc->sc_dev = self; memset(compat, 0, sizeof(compat)); OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat)); if (strcmp(compat, "u3-agp") == 0) ver = 3; else if (strcmp(compat, "u4-pcie") == 0) ver = 4; else ver = 0; /* UniNorth address */ if (OF_getprop(node, "reg", reg, sizeof(reg)) < 8) return; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; memset(&sc->sc_iot, 0, sizeof(sc->sc_iot)); /* find i/o tag */ len = OF_getprop(node, "ranges", ranges, sizeof(ranges)); if (len == -1) return; while (len >= sizeof(ranges[0])) { if ((rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) == OFW_PCI_PHYS_HI_SPACE_IO) { sc->sc_iot.pbs_base = rp->host; sc->sc_iot.pbs_limit = rp->host + rp->size_lo; break; } len -= sizeof(ranges[0]); rp++; } /* XXX enable gmac ethernet */ for (child = OF_child(node); child; child = OF_peer(child)) { volatile int *gmac_gbclock_en = (void *)0xf8000020; memset(compat, 0, sizeof(compat)); OF_getprop(child, "compatible", compat, sizeof(compat)); if (strcmp(compat, "gmac") == 0) *gmac_gbclock_en |= 0x02; } sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_offset = 0; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "uninorth io-space") != 0) panic("Can't init uninorth io tag"); memset(&sc->sc_memt, 0, sizeof(sc->sc_memt)); sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE; sc->sc_memt.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt, "uninorth mem-space") != 0) panic("Can't init uninorth mem tag"); macppc_pci_get_chipset_tag(pc); pc->pc_node = node; pc->pc_bus = busrange[0]; pc->pc_iot = &sc->sc_iot; pc->pc_memt = &sc->sc_memt; if (ver < 3) { pc->pc_addr = mapiodev(reg[0] + 0x800000, 4, false); pc->pc_data = mapiodev(reg[0] + 0xc00000, 8, false); pc->pc_conf_read = uninorth_conf_read; pc->pc_conf_write = uninorth_conf_write; } else { pc->pc_addr = mapiodev(reg[1] + 0x800000, 4, false); pc->pc_data = mapiodev(reg[1] + 0xc00000, 8, false); pc->pc_conf_read = uninorth_conf_read_v3; pc->pc_conf_write = uninorth_conf_write_v3; } memset(&pba, 0, sizeof(pba)); pba.pba_memt = pc->pc_memt; pba.pba_iot = pc->pc_iot; pba.pba_dmat = &pci_bus_dma_tag; pba.pba_dmat64 = NULL; pba.pba_bus = pc->pc_bus; pba.pba_bridgetag = NULL; pba.pba_pc = pc; pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY; config_found_ia(self, "pcibus", &pba, pcibusprint); }
hide void mc_attach(device_t parent, device_t self, void *aux) { struct confargs *ca = aux; struct mc_softc *sc = device_private(self); u_int8_t myaddr[ETHER_ADDR_LEN]; u_int *reg; sc->sc_dev = self; sc->sc_node = ca->ca_node; sc->sc_regt = ca->ca_tag; reg = ca->ca_reg; reg[0] += ca->ca_baseaddr; reg[2] += ca->ca_baseaddr; reg[4] += ca->ca_baseaddr; sc->sc_txdma = mapiodev(reg[2], reg[3], false); sc->sc_rxdma = mapiodev(reg[4], reg[5], false); bus_space_map(sc->sc_regt, reg[0], reg[1], 0, &sc->sc_regh); sc->sc_tail = 0; sc->sc_txdmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 2, NULL); sc->sc_rxdmacmd = (void *)dbdma_alloc(sizeof(dbdma_command_t) * 8, NULL); memset(sc->sc_txdmacmd, 0, sizeof(dbdma_command_t) * 2); memset(sc->sc_rxdmacmd, 0, sizeof(dbdma_command_t) * 8); printf(": irq %d,%d,%d", ca->ca_intr[0], ca->ca_intr[1], ca->ca_intr[2]); if (OF_getprop(sc->sc_node, "local-mac-address", myaddr, 6) != 6) { printf(": failed to get MAC address.\n"); return; } /* allocate memory for transmit buffer and mark it non-cacheable */ sc->sc_txbuf = malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK); sc->sc_txbuf_phys = kvtop(sc->sc_txbuf); memset(sc->sc_txbuf, 0, PAGE_SIZE); /* * allocate memory for receive buffer and mark it non-cacheable * XXX This should use the bus_dma interface, since the buffer * needs to be physically contiguous. However, it seems that * at least on my system, malloc() does allocate contiguous * memory. If it's not, suggest reducing the number of buffers * to 2, which will fit in one 4K page. */ sc->sc_rxbuf = malloc(MC_NPAGES * PAGE_SIZE, M_DEVBUF, M_WAITOK); sc->sc_rxbuf_phys = kvtop(sc->sc_rxbuf); memset(sc->sc_rxbuf, 0, MC_NPAGES * PAGE_SIZE); if ((int)sc->sc_txbuf & PGOFSET) printf("txbuf is not page-aligned\n"); if ((int)sc->sc_rxbuf & PGOFSET) printf("rxbuf is not page-aligned\n"); sc->sc_bus_init = mc_init; sc->sc_putpacket = mc_putpacket; /* disable receive DMA */ dbdma_reset(sc->sc_rxdma); /* disable transmit DMA */ dbdma_reset(sc->sc_txdma); /* install interrupt handlers */ /*intr_establish(ca->ca_intr[1], IST_EDGE, IPL_NET, mc_dmaintr, sc);*/ intr_establish(ca->ca_intr[2], IST_EDGE, IPL_NET, mc_dmaintr, sc); intr_establish(ca->ca_intr[0], IST_EDGE, IPL_NET, mcintr, sc); sc->sc_biucc = XMTSP_64; sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST; /*sc->sc_plscc = PORTSEL_10BT;*/ sc->sc_plscc = PORTSEL_GPSI | ENPLSIO; /* mcsetup returns 1 if something fails */ if (mcsetup(sc, myaddr)) { printf("mcsetup returns non zero\n"); return; } #ifdef NOTYET sc->sc_mediachange = mc_mediachange; sc->sc_mediastatus = mc_mediastatus; sc->sc_supmedia = mc_supmedia; sc->sc_nsupmedia = N_SUPMEDIA; sc->sc_defaultmedia = IFM_ETHER | IFM_10_T; #endif }
void cgtwelveattach(struct device *parent, struct device *self, void *args) { struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self; struct confargs *ca = args; int node; int isconsole = 0; char *ps; node = ca->ca_ra.ra_node; printf(": %s", getpropstring(node, "model")); ps = getpropstring(node, "dev_id"); if (*ps != '\0') printf(" (%s)", ps); printf("\n"); isconsole = node == fbnode; sc->sc_phys = ca->ca_ra.ra_reg[0]; /* * Map registers */ sc->sc_dpu = (struct cgtwelve_dpu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DPU, sizeof(struct cgtwelve_dpu)); sc->sc_apu = (struct cgtwelve_apu *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_APU, sizeof(struct cgtwelve_apu)); sc->sc_ramdac = (struct cgtwelve_dac *)mapiodev(ca->ca_ra.ra_reg, CG12_OFF_DAC, sizeof(struct cgtwelve_dac)); /* * The console is using the 1-bit overlay plane, while the prom * will correctly report 32 bit depth. */ fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT, node, ca->ca_bustype); sc->sc_sunfb.sf_depth = 1; sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes; sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR; /* * Map planes */ sc->sc_overlay = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0, round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR : CG12_SIZE_OVERLAY)); sc->sc_inten = mapiodev(ca->ca_ra.ra_reg, sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN, round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR : CG12_SIZE_COLOR24)); /* reset cursor & frame buffer controls */ sc->sc_sunfb.sf_depth = 0; /* force action */ cgtwelve_reset(sc, 1); sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay; sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); if (isconsole) { fbwscons_console_init(&sc->sc_sunfb, -1); shutdownhook_establish(cgtwelve_prom, sc); } printf("%s: %dx%d", self->dv_xname, sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); ps = getpropstring(node, "ucoderev"); if (*ps != '\0') printf(", microcode rev. %s", ps); printf("\n"); fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole); }