void fb_setsize(struct sunfb *sf, int def_depth, int def_width, int def_height, int node, int unused) { int def_linebytes; sf->sf_depth = getpropint(node, "depth", def_depth); sf->sf_width = getpropint(node, "width", def_width); sf->sf_height = getpropint(node, "height", def_height); def_linebytes = roundup(sf->sf_width, sf->sf_depth) * sf->sf_depth / 8; sf->sf_linebytes = getpropint(node, "linebytes", def_linebytes); /* * XXX If we are configuring a board in a wider depth level * than the mode it is currently operating in, the PROM will * return a linebytes property tied to the current depth value, * which is NOT what we are relying upon! */ if (sf->sf_linebytes < (sf->sf_width * sf->sf_depth) / 8) { sf->sf_linebytes = def_linebytes; } sf->sf_fbsize = sf->sf_height * sf->sf_linebytes; }
int vbus_intr_map(int node, int ino, uint64_t *sysino) { int *imap = NULL, nimap; int *reg = NULL, nreg; int *imap_mask; int parent; int address_cells, interrupt_cells; uint64_t devhandle; uint64_t devino; int len; int err; parent = OF_parent(node); address_cells = getpropint(parent, "#address-cells", 2); interrupt_cells = getpropint(parent, "#interrupt-cells", 1); KASSERT(interrupt_cells == 1); len = OF_getproplen(parent, "interrupt-map-mask"); if (len < (address_cells + interrupt_cells) * sizeof(int)) return (-1); imap_mask = malloc(len, M_DEVBUF, M_NOWAIT); if (imap_mask == NULL) return (-1); if (OF_getprop(parent, "interrupt-map-mask", imap_mask, len) != len) return (-1); getprop(parent, "interrupt-map", sizeof(int), &nimap, (void **)&imap); getprop(node, "reg", sizeof(*reg), &nreg, (void **)®); if (nreg < address_cells) return (-1); while (nimap >= address_cells + interrupt_cells + 2) { if (vbus_cmp_cells(imap, reg, imap_mask, address_cells) && vbus_cmp_cells(&imap[address_cells], &ino, &imap_mask[address_cells], interrupt_cells)) { node = imap[address_cells + interrupt_cells]; devino = imap[address_cells + interrupt_cells + 1]; free(reg, M_DEVBUF, 0); reg = NULL; getprop(node, "reg", sizeof(*reg), &nreg, (void **)®); devhandle = reg[0] & 0x0fffffff; err = hv_intr_devino_to_sysino(devhandle, devino, sysino); if (err != H_EOK) return (-1); KASSERT(*sysino == INTVEC(*sysino)); return (0); } imap += address_cells + interrupt_cells + 2; nimap -= address_cells + interrupt_cells + 2; } return (-1); }
void tcx_accel_init(struct tcx_softc *sc, struct confargs *ca) { int stipple_align, regno; /* * On S24, try and map raw blit and raw stipple spaces. * We prefer the raw spaces so that we can eventually switch * between 8 bit and 24 bit modes with blitter operations. * * However, on 8-bit TCX, these spaces are missing (and empty!), * so we should fallback to non-raw spaces in this case. * * Since this frame buffer can only exist on SS4 and SS5, * we can rely upon the fact this code will only run on sun4m, * and use stda() bypassing the MMU to access these spaces, * instead of mapping them (8MB KVA each, after all, even more * on an SS4 with the resolution extender VSIMM). */ sc->sc_blit_width = getpropint(ca->ca_ra.ra_node, "blit-width", 0); if (sc->sc_blit_width > 5) sc->sc_blit_width = 5; /* paranoia */ if (sc->sc_blit_width <= 3) /* not worth until more than 8 pixels */ sc->sc_blit_width = 0; else { sc->sc_blit_width = 1 << sc->sc_blit_width; regno = sc->sc_cplane == 0 ? TCX_REG_BLIT : TCX_REG_RBLIT; if (ca->ca_ra.ra_reg[regno].rr_len >= sc->sc_sunfb.sf_fbsize * 8) sc->sc_blit = (paddr_t)ca->ca_ra.ra_reg[regno].rr_paddr; } /* * Do not assume the stipple space is usable unless there is a * `stipple-align' property. Also, don't try to use it if the * alignment is not 32 - our code may not behave correctly. */ stipple_align = getpropint(ca->ca_ra.ra_node, "stipple-align", 0); if (stipple_align == 5) { regno = sc->sc_cplane == 0 ? TCX_REG_STIP : TCX_REG_RSTIP; if (ca->ca_ra.ra_reg[regno].rr_len >= sc->sc_sunfb.sf_fbsize * 8) sc->sc_stipple = (paddr_t)ca->ca_ra.ra_reg[regno].rr_paddr; } }
void leattach_lebuffer(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct le_softc *lesc = (struct le_softc *)self; struct am7990_softc *sc = &lesc->sc_am7990; struct lebuf_softc *lebuf = (struct lebuf_softc *)parent; /* XXX the following declarations should be elsewhere */ extern void myetheraddr(u_char *); lesc->sc_bustag = sa->sa_bustag; lesc->sc_dmatag = sa->sa_dmatag; if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, 0, 0, &lesc->sc_reg)) { printf(": cannot map registers\n"); return; } sc->sc_mem = lebuf->sc_buffer; sc->sc_memsize = lebuf->sc_bufsiz; sc->sc_addr = 0; /* Lance view is offset by buffer location */ lebuf->attached = 1; /* That old black magic... */ sc->sc_conf3 = getpropint(sa->sa_node, "busmaster-regval", LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON); myetheraddr(sc->sc_arpcom.ac_enaddr); sc->sc_copytodesc = am7990_copytobuf_contig; sc->sc_copyfromdesc = am7990_copyfrombuf_contig; sc->sc_copytobuf = am7990_copytobuf_contig; sc->sc_copyfrombuf = am7990_copyfrombuf_contig; sc->sc_zerobuf = am7990_zerobuf_contig; sc->sc_rdcsr = le_lebuffer_rdcsr; sc->sc_wrcsr = le_lebuffer_wrcsr; am7990_config(&lesc->sc_am7990); /* Establish interrupt handler */ if (sa->sa_nintr != 0) (void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri, IPL_NET, 0, am7990_intr, sc, self->dv_xname); }
void zx_attach(struct device *parent, struct device *self, void *args) { struct zx_softc *sc = (struct zx_softc *)self; struct sbus_attach_args *sa = args; struct rasops_info *ri; bus_space_tag_t bt; bus_space_handle_t bh; int node, isconsole = 0; const char *nam; bt = sa->sa_bustag; ri = &sc->sc_sunfb.sf_ro; node = sa->sa_node; /* * Map the various parts of the card. */ sc->sc_bustag = bt; sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR, sizeof(struct zx_command), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf(": couldn't map command registers\n"); return; } sc->sc_zc = (struct zx_command *)bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0, sizeof(struct zx_draw), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf(": couldn't map ss0 drawing registers\n"); return; } sc->sc_zd_ss0 = (struct zx_draw *)bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1, sizeof(struct zx_draw_ss1), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf(": couldn't map ss1 drawing registers\n"); return; } sc->sc_zd_ss1 = (struct zx_draw_ss1 *)bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS, sizeof(struct zx_cross), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf(": couldn't map cross registers\n"); return; } sc->sc_zx = (struct zx_cross *)bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR, sizeof(struct zx_cursor), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf(": couldn't map cursor registers\n"); return; } sc->sc_zcu = (struct zx_cursor *)bus_space_vaddr(bt, bh); nam = getpropstring(node, "model"); if (*nam == '\0') nam = sa->sa_name; printf(": %s", nam); isconsole = node == fbnode; /* * The console is using the 8-bit overlay plane, while the prom * will correctly report 32 bit depth. * The following is an equivalent for * fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype); * forcing the depth value not to be overwritten. * Furthermore, the linebytes value is in fact 8192 bytes. */ sc->sc_sunfb.sf_depth = 8; sc->sc_sunfb.sf_width = getpropint(node, "width", 1152); sc->sc_sunfb.sf_height = getpropint(node, "height", 900); sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH; sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH; printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0, round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: couldn't map video memory\n", self->dv_xname); return; } ri->ri_bits = bus_space_vaddr(bt, bh); ri->ri_hw = sc; fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR); /* * Watch out! rasops_init() invoked via fbwscons_init() did not * compute ri_bits correctly when centering the display, because * it has been tricked with the low depth value. * Recompute now. */ ri->ri_emustride = ri->ri_emuwidth * 4; ri->ri_delta = ri->ri_stride - ri->ri_emustride; ri->ri_pelbytes = 4; ri->ri_xscale = ri->ri_font->fontwidth * 4; ri->ri_bits = ri->ri_origbits; ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3; ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) * ri->ri_stride; ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits) / ri->ri_stride; ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits) % ri->ri_stride) / 4); ri->ri_ops.copyrows = zx_copyrows; ri->ri_ops.copycols = zx_copycols; ri->ri_ops.eraserows = zx_eraserows; ri->ri_ops.erasecols = zx_erasecols; ri->ri_ops.putchar = zx_putchar; ri->ri_do_cursor = zx_do_cursor; if (isconsole) { /* zx_reset() below will clear screen, so restart at 1st row */ fbwscons_console_init(&sc->sc_sunfb, 0); } /* reset cursor & frame buffer controls */ zx_reset(sc, WSDISPLAYIO_MODE_EMUL); /* enable video */ zx_burner(sc, 1, 0); fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole); }
void fb_setsize(struct sunfb *sf, int def_depth, int def_width, int def_height, int node, int bustype) { int def_linebytes; switch (bustype) { case BUS_VME16: case BUS_VME32: case BUS_OBIO: #if defined(SUN4M) /* 4m may have SBus-like framebuffer on obio */ if (CPU_ISSUN4M) { goto obpsize; } #endif /* Set up some defaults. */ sf->sf_width = def_width; sf->sf_height = def_height; sf->sf_depth = def_depth; #if defined(SUN4) /* * This is not particularly useful on Sun 4 VME framebuffers. * The EEPROM only contains info about the built-in. */ if (CPU_ISSUN4 && bustype == BUS_OBIO) { struct eeprom *eep = (struct eeprom *)eeprom_va; if (ISSET(sf->sf_flags, FB_PFOUR)) { volatile u_int32_t pfour; u_int size; pfour = *sf->sf_pfour; /* * Use the pfour register to determine * the size. Note that the cgsix and * cgeight don't use this size encoding. * In this case, we have to settle * for the defaults we were provided * with. */ if ((PFOUR_ID(pfour) == PFOUR_ID_COLOR24) || (PFOUR_ID(pfour) == PFOUR_ID_FASTCOLOR)) size = 0x00; /* invalid */ else size = PFOUR_SIZE(pfour); switch (size) { case PFOUR_SIZE_1152X900: sf->sf_width = 1152; sf->sf_height = 900; break; case PFOUR_SIZE_1024X1024: sf->sf_width = 1024; sf->sf_height = 1024; break; case PFOUR_SIZE_1280X1024: sf->sf_width = 1280; sf->sf_height = 1024; break; case PFOUR_SIZE_1600X1280: sf->sf_width = 1600; sf->sf_height = 1280; break; case PFOUR_SIZE_1440X1440: sf->sf_width = 1440; sf->sf_height = 1440; break; case PFOUR_SIZE_640X480: sf->sf_width = 640; sf->sf_height = 480; break; } } else if (eep != NULL) { switch (eep->eeScreenSize) { case EE_SCR_1152X900: sf->sf_width = 1152; sf->sf_height = 900; break; case EE_SCR_1024X1024: sf->sf_width = 1024; sf->sf_height = 1024; break; case EE_SCR_1600X1280: sf->sf_width = 1600; sf->sf_height = 1280; break; case EE_SCR_1440X1440: sf->sf_width = 1440; sf->sf_height = 1440; break; } } } #endif /* SUN4 */ #if defined(SUN4M) if (CPU_ISSUN4M) { /* XXX: need code to find 4/600 vme screen size */ } #endif /* SUN4M */ sf->sf_linebytes = (sf->sf_width * sf->sf_depth) / 8; break; case BUS_SBUS: #if defined(SUN4M) obpsize: #endif sf->sf_depth = getpropint(node, "depth", def_depth); sf->sf_width = getpropint(node, "width", def_width); sf->sf_height = getpropint(node, "height", def_height); def_linebytes = roundup(sf->sf_width, sf->sf_depth) * sf->sf_depth / 8; sf->sf_linebytes = getpropint(node, "linebytes", def_linebytes); /* * XXX If we are configuring a board in a wider depth level * than the mode it is currently operating in, the PROM will * return a linebytes property tied to the current depth value, * which is NOT what we are relying upon! */ if (sf->sf_linebytes < (sf->sf_width * sf->sf_depth) / 8) sf->sf_linebytes = def_linebytes; break; } sf->sf_fbsize = sf->sf_height * sf->sf_linebytes; }
void com_ebus_attach(struct device *parent, struct device *self, void *aux) { struct com_softc *sc = (void *)self; struct ebus_attach_args *ea = aux; int i, com_is_input, com_is_output; int node, port; char buf[32]; sc->sc_iobase = EBUS_PADDR_FROM_REG(&ea->ea_regs[0]); /* * Addresses that should be supplied by the prom: * - normal com registers * - ns873xx configuration registers * - DMA space * The `com' driver does not use DMA accesses, so we can * ignore that for now. We should enable the com port in * the ns873xx registers here. XXX * * Use the prom address if there. */ if (ea->ea_nvaddrs) { if (bus_space_map(ea->ea_memtag, ea->ea_vaddrs[0], 0, BUS_SPACE_MAP_PROMADDRESS, &sc->sc_ioh) != 0) { printf(": can't map register space\n"); return; } sc->sc_iot = ea->ea_memtag; } else if (ebus_bus_map(ea->ea_memtag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { sc->sc_iot = ea->ea_memtag; } else if (ebus_bus_map(ea->ea_iotag, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[0]), ea->ea_regs[0].size, 0, 0, &sc->sc_ioh) == 0) { sc->sc_iot = ea->ea_iotag; } else { printf(": can't map register space\n"); return; } sc->sc_hwflags = 0; sc->sc_swflags = 0; sc->sc_frequency = BAUD_BASE; for (i = 0; i < ea->ea_nintrs; i++) bus_intr_establish(sc->sc_iot, ea->ea_intrs[i], IPL_TTY, 0, comintr, sc, self->dv_xname); /* * Figure out if we're the console. * * The Fujitsu SPARC Enterprise M4000/M5000/M8000/M9000 has a * serial port on each I/O board and a pseudo console that is * redirected to one of these serial ports. The board number * of the serial port in question is encoded in the "tty-port#" * property of the pseudo console, so we figure out what our * board number is by walking up the device tree, and check * for a match. */ node = OF_instance_to_package(OF_stdin()); com_is_input = (ea->ea_node == node); if (OF_getprop(node, "name", buf, sizeof(buf)) > 0 && strcmp(buf, "pseudo-console") == 0) { port = getpropint(node, "tty-port#", -1); node = OF_parent(OF_parent(ea->ea_node)); com_is_input = (getpropint(node, "board#", -2) == port); } node = OF_instance_to_package(OF_stdout()); com_is_output = (ea->ea_node == node); if (OF_getprop(node, "name", buf, sizeof(buf)) > 0 && strcmp(buf, "pseudo-console") == 0) { port = getpropint(node, "tty-port#", -1); node = OF_parent(OF_parent(ea->ea_node)); com_is_output = (getpropint(node, "board#", -2) == port); } if (com_is_input || com_is_output) { struct consdev *cn_orig; int speed; speed = com_ebus_speed(ea); comconsioh = sc->sc_ioh; cn_orig = cn_tab; /* Attach com as the console. */ if (comcnattach(sc->sc_iot, sc->sc_iobase, speed, sc->sc_frequency, ((TTYDEF_CFLAG & ~(CSIZE | PARENB))|CREAD | CS8 | HUPCL))) { printf("Error: comcnattach failed\n"); } cn_tab = cn_orig; if (com_is_input) { cn_tab->cn_dev = /*XXX*/makedev(36, sc->sc_dev.dv_unit); cn_tab->cn_probe = comcnprobe; cn_tab->cn_init = comcninit; cn_tab->cn_getc = comcngetc; cn_tab->cn_pollc = comcnpollc; } if (com_is_output) cn_tab->cn_putc = comcnputc; } /* * Apparently shoving too much data down the TX FIFO on the * Fujitsu SPARC Enterprise M4000/M5000 causes a hardware * fault. Avoid this issue by setting the FIFO depth to 1. * This will effectively disable the TX FIFO, but will still * enable the RX FIFO, which is what we really care about. */ if (OF_getprop(ea->ea_node, "compatible", buf, sizeof(buf)) > 0 && strcmp(buf, "FJSV,su") == 0) sc->sc_uarttype = COM_UART_16550; if (OF_getproplen(ea->ea_node, "keyboard") == 0) printf(": keyboard"); else if (OF_getproplen(ea->ea_node, "mouse") == 0) printf(": mouse"); /* Now attach the driver */ com_attach_subr(sc); }
/* * Attach an MGX frame buffer. * This will keep the frame buffer in the actual PROM mode, and attach * a wsdisplay child device to itself. */ void mgxattach(struct device *parent, struct device *self, void *args) { struct mgx_softc *sc = (struct mgx_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, fbsize; int isconsole; uint16_t chipid; bt = sa->sa_bustag; node = sa->sa_node; printf(": %s", getpropstring(node, "model")); isconsole = node == fbnode; /* Check registers */ if (sa->sa_nreg < MGX_NREG) { printf("\n%s: expected %d registers, got %d\n", self->dv_xname, MGX_NREG, sa->sa_nreg); return; } sc->sc_bustag = bt; if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_CRTC].sbr_slot, sa->sa_reg[MGX_REG_CRTC].sbr_offset, PAGE_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map crtc registers\n", self->dv_xname); return; } sc->sc_vidc = (vaddr_t)bus_space_vaddr(bt, bh); sc->sc_bustag = bt; if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_ATREG].sbr_slot, sa->sa_reg[MGX_REG_ATREG].sbr_offset + MGX_REG_ATREG_OFFSET, MGX_REG_ATREG_SIZE, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map crtc registers\n", self->dv_xname); /* XXX unmap vidc */ return; } sc->sc_xreg = (vaddr_t)bus_space_vaddr(bt, bh); /* * Check the chip ID. If it's not an AT24, prefer not to access * the extended registers at all. */ chipid = mgx_read_2(sc->sc_xreg, ATR_ID); if (chipid != ID_AT24) { sc->sc_xreg = (vaddr_t)0; } /* enable video */ mgx_burner(sc, 1, 0); fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0); /* Sanity check frame buffer memory */ fbsize = getpropint(node, "fb_size", 0); if (fbsize != 0 && sc->sc_sunfb.sf_fbsize > fbsize) { printf("\n%s: expected at least %d bytes of vram, but card " "only provides %d\n", self->dv_xname, sc->sc_sunfb.sf_fbsize, fbsize); return; } /* Map the frame buffer memory area we're interested in */ sc->sc_paddr = sbus_bus_addr(bt, sa->sa_reg[MGX_REG_VRAM8].sbr_slot, sa->sa_reg[MGX_REG_VRAM8].sbr_offset); if (sbus_bus_map(bt, sa->sa_reg[MGX_REG_VRAM8].sbr_slot, sa->sa_reg[MGX_REG_VRAM8].sbr_offset, round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map video memory\n", self->dv_xname); /* XXX unmap vidc and xreg */ return; } sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh); sc->sc_sunfb.sf_ro.ri_hw = sc; printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height); fbwscons_init(&sc->sc_sunfb, 0, isconsole); bzero(sc->sc_cmap, sizeof(sc->sc_cmap)); fbwscons_setcolormap(&sc->sc_sunfb, mgx_setcolor); if (chipid != ID_AT24) { printf("%s: unexpected engine id %04x\n", self->dv_xname, chipid); } mgx_ras_init(sc, chipid); if (isconsole) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &mgx_accessops, isconsole); }
/* * Attach all the sub-devices we can find */ void lebufattach(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct lebuf_softc *sc = (void *)self; int node; int sbusburst; struct sparc_bus_space_tag *sbt; bus_space_handle_t bh; sc->sc_bustag = sa->sa_bustag; sc->sc_dmatag = sa->sa_dmatag; if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("%s: attach: cannot map registers\n", self->dv_xname); return; } /* * This device's "register space" is just a buffer where the * Lance ring-buffers can be stored. Note the buffer's location * and size, so the `le' driver can pick them up. */ sc->sc_buffer = (void *)bus_space_vaddr(sa->sa_bustag, bh); sc->sc_bufsiz = sa->sa_size; node = sc->sc_node = sa->sa_node; /* * Get transfer burst size from PROM */ sbusburst = ((struct sbus_softc *)parent)->sc_burst; if (sbusburst == 0) sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ sc->sc_burst = getpropint(node, "burst-sizes", -1); if (sc->sc_burst == -1) /* take SBus burst sizes */ sc->sc_burst = sbusburst; /* Clamp at parent's burst sizes */ sc->sc_burst &= sbusburst; /* Allocate a bus tag */ sbt = malloc(sizeof(*sbt), M_DEVBUF, M_NOWAIT | M_ZERO); if (sbt == NULL) { printf("%s: attach: out of memory\n", self->dv_xname); return; } printf(": %dK memory\n", sc->sc_bufsiz / 1024); sbt->cookie = sc; sbt->parent = sc->sc_bustag; sbt->asi = sbt->parent->asi; sbt->sasi = sbt->parent->sasi; /* search through children */ for (node = firstchild(node); node; node = nextsibling(node)) { struct sbus_attach_args sa; sbus_setup_attach_args((struct sbus_softc *)parent, sbt, sc->sc_dmatag, node, &sa); (void)config_found(&sc->sc_dev, (void *)&sa, lebufprint); sbus_destroy_attach_args(&sa); } }
void bppattach(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct bpp_softc *dsc = (void *)self; struct lsi64854_softc *sc = &dsc->sc_lsi64854; int burst, sbusburst; int node; node = sa->sa_node; sc->sc_bustag = sa->sa_bustag; sc->sc_dmatag = sa->sa_dmatag; /* Map device registers */ if (sa->sa_npromvaddrs != 0) { if (sbus_bus_map(sa->sa_bustag, 0, sa->sa_promvaddrs[0], sa->sa_size, /* ???? */ BUS_SPACE_MAP_PROMADDRESS, 0, &sc->sc_regs) != 0) { printf(": cannot map registers\n"); return; } } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, sa->sa_offset, sa->sa_size, 0, 0, &sc->sc_regs) != 0) { printf(": cannot map registers\n"); return; } /* Check for the interrupt property */ if (sa->sa_nintr == 0) { printf(": no interrupt property\n"); return; } /* * Get transfer burst size from PROM and plug it into the * controller registers. This is needed on the Sun4m; do * others need it too? */ sbusburst = ((struct sbus_softc *)parent)->sc_burst; if (sbusburst == 0) sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ burst = getpropint(node, "burst-sizes", -1); if (burst == -1) /* take SBus burst sizes */ burst = sbusburst; /* Clamp at parent's burst sizes */ burst &= sbusburst; sc->sc_burst = (burst & SBUS_BURST_32) ? 32 : (burst & SBUS_BURST_16) ? 16 : 0; /* Initialize the DMA channel */ sc->sc_channel = L64854_CHANNEL_PP; if (lsi64854_attach(sc) != 0) return; /* Establish interrupt handler */ sc->sc_intrchain = bppintr; sc->sc_intrchainarg = dsc; (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0, bppintr, sc, self->dv_xname); /* Allocate buffer XXX - should actually use dmamap_uio() */ dsc->sc_bufsz = 1024; dsc->sc_buf = malloc(dsc->sc_bufsz, M_DEVBUF, M_NOWAIT); /* XXX read default state */ { bus_space_handle_t h = sc->sc_regs; struct hwstate *hw = &dsc->sc_hwstate; int ack_rate = sa->sa_frequency/1000000; hw->hw_hcr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_HCR); hw->hw_ocr = bus_space_read_2(sc->sc_bustag, h, L64854_REG_OCR); hw->hw_tcr = bus_space_read_1(sc->sc_bustag, h, L64854_REG_TCR); hw->hw_or = bus_space_read_1(sc->sc_bustag, h, L64854_REG_OR); DPRINTF(("bpp: hcr %x ocr %x tcr %x or %x\n", hw->hw_hcr, hw->hw_ocr, hw->hw_tcr, hw->hw_or)); /* Set these to sane values */ hw->hw_hcr = ((ack_rate<<BPP_HCR_DSS_SHFT)&BPP_HCR_DSS_MASK) | ((ack_rate<<BPP_HCR_DSW_SHFT)&BPP_HCR_DSW_MASK); hw->hw_ocr |= BPP_OCR_ACK_OP; } }
void agtenattach(struct device *parent, struct device *self, void *args) { struct agten_softc *sc = (struct agten_softc *)self; struct sbus_attach_args *sa = args; bus_space_tag_t bt; bus_space_handle_t bh; int node, isconsole; char *nam; bt = sa->sa_bustag; node = sa->sa_node; nam = getpropstring(node, "model"); printf(": model %s", nam); isconsole = node == fbnode; /* * Map the various beasts of this card we are interested in. */ sc->sc_bustag = bt; sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset); sc->sc_physoffset = (off_t)getpropint(node, "i128_fb_physaddr", 0x8000000); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + sc->sc_physoffset, getpropint(node, "i128_fb_size", 0x400000), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map video memory\n", self->dv_xname); return; } sc->sc_i128_fb = bus_space_vaddr(bt, bh); if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + getpropint(node, "p9100_reg_physaddr", 0x10a0000), 0x4000, BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) { printf("\n%s: couldn't map control registers\n", self->dv_xname); return; } sc->sc_p9100 = bus_space_vaddr(bt, bh); /* * 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, 0, isconsole); fbwscons_setcolormap(&sc->sc_sunfb, agten_setcolor); if (isconsole) fbwscons_console_init(&sc->sc_sunfb, -1); fbwscons_attach(&sc->sc_sunfb, &agten_accessops, isconsole); }
void cs4231_attach(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct cs4231_softc *sc = (struct cs4231_softc *)self; int node; u_int32_t sbusburst, burst; node = sa->sa_node; /* Pass on the bus tags */ sc->sc_bustag = sa->sa_bustag; sc->sc_dmatag = sa->sa_dmatag; /* Make sure things are sane. */ if (sa->sa_nintr != 1) { printf(": expected 1 interrupt, got %d\n", sa->sa_nintr); return; } if (sa->sa_nreg != 1) { printf(": expected 1 register set, got %d\n", sa->sa_nreg); return; } if (bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_AUDIO, 0, cs4231_intr, sc, self->dv_xname) == NULL) { printf(": couldn't establish interrupt, pri %d\n", INTLEV(sa->sa_pri)); return; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &sc->sc_regs) != 0) { printf(": couldn't map registers\n"); return; } sbusburst = ((struct sbus_softc *)parent)->sc_burst; if (sbusburst == 0) sbusburst = SBUS_BURST_32 - 1; /* 1->16 */ burst = getpropint(node, "burst-sizes", -1); if (burst == -1) burst = sbusburst; sc->sc_burst = burst & sbusburst; printf("\n"); audio_attach_mi(&cs4231_sa_hw_if, sc, &sc->sc_dev); /* Default to speaker, unmuted, reasonable volume */ sc->sc_out_port = CSPORT_SPEAKER; sc->sc_in_port = CSPORT_MICROPHONE; sc->sc_mute[CSPORT_SPEAKER] = 1; sc->sc_mute[CSPORT_MONITOR] = 1; sc->sc_volume[CSPORT_SPEAKER].left = 192; sc->sc_volume[CSPORT_SPEAKER].right = 192; }
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 leattach_sbus(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct le_softc *lesc = (struct le_softc *)self; struct lance_softc *sc = &lesc->sc_am7990.lsc; bus_dma_tag_t dmatag; /* XXX the following declarations should be elsewhere */ extern void myetheraddr(u_char *); extern struct cfdriver lebuffer_cd; lesc->sc_bustag = sa->sa_bustag; lesc->sc_dmatag = dmatag = sa->sa_dmatag; if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size, BUS_SPACE_MAP_LINEAR, 0, &lesc->sc_reg) != 0) { printf(": cannot map registers\n"); return; } /* * Look for an "unallocated" lebuffer and pair it with * this `le' device on the assumption that we're on * a pre-historic ROM that doesn't establish le<=>lebuffer * parent-child relationships. */ if (lebuffer_cd.cd_ndevs != 0) { struct lebuf_softc *lebuf; int i; for (i = 0; i < lebuffer_cd.cd_ndevs; i++) { lebuf = (struct lebuf_softc *)lebuffer_cd.cd_devs[i]; if (lebuf == NULL || lebuf->attached != 0) continue; sc->sc_mem = lebuf->sc_buffer; sc->sc_memsize = lebuf->sc_bufsiz; /* Lance view is offset by buffer location */ sc->sc_addr = 0; lebuf->attached = 1; /* That old black magic... */ sc->sc_conf3 = getpropint(sa->sa_node, "busmaster-regval", LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON); break; } } if (sc->sc_mem == 0) { bus_dma_segment_t seg; int rseg, error; /* Get a DMA handle */ if ((error = bus_dmamap_create(dmatag, MEMSIZE, 1, MEMSIZE, 0, BUS_DMA_NOWAIT|BUS_DMA_24BIT, &lesc->sc_dmamap)) != 0) { printf(": DMA map create error %d\n", error); return; } /* Allocate DMA buffer */ if ((error = bus_dmamem_alloc(dmatag, MEMSIZE, 0, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT|BUS_DMA_24BIT)) != 0){ printf(": DMA buffer allocation error %d\n", error); return; } /* Map DMA buffer into kernel space */ if ((error = bus_dmamem_map(dmatag, &seg, rseg, MEMSIZE, (caddr_t *)&sc->sc_mem, BUS_DMA_NOWAIT|BUS_DMA_COHERENT|BUS_DMA_24BIT)) != 0) { printf(": DMA buffer map error %d\n", error); bus_dmamem_free(lesc->sc_dmatag, &seg, rseg); return; } /* Load DMA buffer */ if ((error = bus_dmamap_load(dmatag, lesc->sc_dmamap, sc->sc_mem, MEMSIZE, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT|BUS_DMA_24BIT)) != 0) { printf(": DMA buffer map load error %d\n", error); bus_dmamem_free(dmatag, &seg, rseg); bus_dmamem_unmap(dmatag, sc->sc_mem, MEMSIZE); return; } sc->sc_addr = lesc->sc_dmamap->dm_segs[0].ds_addr & 0xffffff; sc->sc_memsize = MEMSIZE; sc->sc_conf3 = LE_C3_BSWP | LE_C3_ACON | LE_C3_BCON; } myetheraddr(sc->sc_arpcom.ac_enaddr); sc->sc_supmedia = lemedia; sc->sc_nsupmedia = nitems(lemedia); sc->sc_defaultmedia = sc->sc_supmedia[sc->sc_nsupmedia - 1]; sc->sc_copytodesc = lance_copytobuf_contig; sc->sc_copyfromdesc = lance_copyfrombuf_contig; sc->sc_copytobuf = lance_copytobuf_contig; sc->sc_copyfrombuf = lance_copyfrombuf_contig; sc->sc_zerobuf = lance_zerobuf_contig; sc->sc_rdcsr = le_sbus_rdcsr; sc->sc_wrcsr = le_sbus_wrcsr; am7990_config(&lesc->sc_am7990); /* Establish interrupt handler */ if (sa->sa_nintr != 0) (void)bus_intr_establish(lesc->sc_bustag, sa->sa_pri, IPL_NET, 0, am7990_intr, sc, self->dv_xname); }
void beattach(struct device *parent, struct device *self, void *aux) { struct sbus_attach_args *sa = aux; struct qec_softc *qec = (struct qec_softc *)parent; struct be_softc *sc = (struct be_softc *)self; struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct mii_data *mii = &sc->sc_mii; struct mii_softc *child; int node = sa->sa_node; bus_dma_tag_t dmatag = sa->sa_dmatag; bus_dma_segment_t seg; bus_size_t size; int instance; int rseg, error; u_int32_t v; extern void myetheraddr(u_char *); /* Pass on the bus tags */ sc->sc_bustag = sa->sa_bustag; sc->sc_dmatag = sa->sa_dmatag; if (sa->sa_nreg < 3) { printf("%s: only %d register sets\n", self->dv_xname, sa->sa_nreg); return; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, (bus_addr_t)sa->sa_reg[0].sbr_offset, (bus_size_t)sa->sa_reg[0].sbr_size, 0, 0, &sc->sc_cr) != 0) { printf("beattach: cannot map registers\n"); return; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[1].sbr_slot, (bus_addr_t)sa->sa_reg[1].sbr_offset, (bus_size_t)sa->sa_reg[1].sbr_size, 0, 0, &sc->sc_br) != 0) { printf("beattach: cannot map registers\n"); return; } if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[2].sbr_slot, (bus_addr_t)sa->sa_reg[2].sbr_offset, (bus_size_t)sa->sa_reg[2].sbr_size, 0, 0, &sc->sc_tr) != 0) { printf("beattach: cannot map registers\n"); return; } sc->sc_qec = qec; sc->sc_qr = qec->sc_regs; sc->sc_rev = getpropint(node, "board-version", -1); printf(" rev %x", sc->sc_rev); bestop(sc); sc->sc_channel = getpropint(node, "channel#", -1); if (sc->sc_channel == -1) sc->sc_channel = 0; sc->sc_burst = getpropint(node, "burst-sizes", -1); if (sc->sc_burst == -1) sc->sc_burst = qec->sc_burst; /* Clamp at parent's burst sizes */ sc->sc_burst &= qec->sc_burst; /* Establish interrupt handler */ if (sa->sa_nintr == 0 || bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, 0, beintr, sc, self->dv_xname) == NULL) { printf(": no interrupt established\n"); return; } myetheraddr(sc->sc_arpcom.ac_enaddr); printf(" address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* * Allocate descriptor ring and buffers. */ /* for now, allocate as many bufs as there are ring descriptors */ sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE; sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE; size = QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ + sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ; /* Get a DMA handle */ if ((error = bus_dmamap_create(dmatag, size, 1, size, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { printf("%s: DMA map create error %d\n", self->dv_xname, error); return; } /* Allocate DMA buffer */ if ((error = bus_dmamem_alloc(sa->sa_dmatag, size, 0, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("%s: DMA buffer alloc error %d\n", self->dv_xname, error); return; } /* Map DMA memory in CPU addressable space */ if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size, &sc->sc_rb.rb_membase, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { printf("%s: DMA buffer map error %d\n", self->dv_xname, error); bus_dmamem_free(sa->sa_dmatag, &seg, rseg); return; } /* Load the buffer */ if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap, sc->sc_rb.rb_membase, size, NULL, BUS_DMA_NOWAIT)) != 0) { printf("%s: DMA buffer map load error %d\n", self->dv_xname, error); bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size); bus_dmamem_free(dmatag, &seg, rseg); return; } sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr; /* * Initialize our media structures and MII info. */ mii->mii_ifp = ifp; mii->mii_readreg = be_mii_readreg; mii->mii_writereg = be_mii_writereg; mii->mii_statchg = be_mii_statchg; ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts); timeout_set(&sc->sc_tick_ch, be_tick, sc); /* * Initialize transceiver and determine which PHY connection to use. */ be_mii_sync(sc); v = bus_space_read_4(sc->sc_bustag, sc->sc_tr, BE_TRI_MGMTPAL); instance = 0; if ((v & MGMT_PAL_EXT_MDIO) != 0) { mii_attach(&sc->sc_dev, mii, 0xffffffff, BE_PHY_EXTERNAL, MII_OFFSET_ANY, 0); child = LIST_FIRST(&mii->mii_phys); if (child == NULL) { /* No PHY attached */ ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance), 0, NULL); ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_NONE,0,instance)); } else { /* * Note: we support just one PHY on the external * MII connector. */ #ifdef DIAGNOSTIC if (LIST_NEXT(child, mii_list) != NULL) { printf("%s: spurious MII device %s attached\n", sc->sc_dev.dv_xname, child->mii_dev.dv_xname); } #endif if (child->mii_phy != BE_PHY_EXTERNAL || child->mii_inst > 0) { printf("%s: cannot accommodate MII device %s" " at phy %d, instance %d\n", sc->sc_dev.dv_xname, child->mii_dev.dv_xname, child->mii_phy, child->mii_inst); } else { sc->sc_phys[instance] = child->mii_phy; } /* * XXX - we can really do the following ONLY if the * phy indeed has the auto negotiation capability!! */ ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance)); /* Mark our current media setting */ be_pal_gate(sc, BE_PHY_EXTERNAL); instance++; } } if ((v & MGMT_PAL_INT_MDIO) != 0) { /* * The be internal phy looks vaguely like MII hardware, * but not enough to be able to use the MII device * layer. Hence, we have to take care of media selection * ourselves. */ sc->sc_mii_inst = instance; sc->sc_phys[instance] = BE_PHY_INTERNAL; /* Use `ifm_data' to store BMCR bits */ ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_10_T,0,instance), 0, NULL); ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_100_TX,0,instance), BMCR_S100, NULL); ifmedia_add(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance), 0, NULL); printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n", self->dv_xname); be_mii_reset(sc, BE_PHY_INTERNAL); /* Only set default medium here if there's no external PHY */ if (instance == 0) { be_pal_gate(sc, BE_PHY_INTERNAL); ifmedia_set(&sc->sc_media, IFM_MAKEWORD(IFM_ETHER,IFM_AUTO,0,instance)); } else be_mii_writereg((void *)sc, BE_PHY_INTERNAL, MII_BMCR, BMCR_ISO); } bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); ifp->if_softc = sc; ifp->if_start = bestart; ifp->if_ioctl = beioctl; ifp->if_watchdog = bewatchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; IFQ_SET_READY(&ifp->if_snd); /* Attach the interface. */ if_attach(ifp); ether_ifattach(ifp); }
struct cpu_info * alloc_cpuinfo(struct mainbus_attach_args *ma) { paddr_t pa0, pa; vaddr_t va, va0; vsize_t sz = 8 * PAGE_SIZE; int portid; struct cpu_info *cpi, *ci; extern paddr_t cpu0paddr; portid = getpropint(ma->ma_node, "upa-portid", -1); if (portid == -1) portid = getpropint(ma->ma_node, "portid", -1); if (portid == -1) portid = getpropint(ma->ma_node, "cpuid", -1); if (portid == -1 && ma->ma_nreg > 0) portid = (ma->ma_reg[0].ur_paddr >> 32) & 0x0fffffff; if (portid == -1) panic("alloc_cpuinfo: portid"); for (cpi = cpus; cpi != NULL; cpi = cpi->ci_next) if (cpi->ci_upaid == portid) return cpi; va = uvm_km_valloc_align(kernel_map, sz, 8 * PAGE_SIZE, 0); if (va == 0) panic("alloc_cpuinfo: no virtual space"); va0 = va; pa0 = cpu0paddr; cpu0paddr += sz; for (pa = pa0; pa < cpu0paddr; pa += PAGE_SIZE, va += PAGE_SIZE) pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); pmap_update(pmap_kernel()); cpi = (struct cpu_info *)(va0 + CPUINFO_VA - INTSTACK); memset((void *)va0, 0, sz); /* * Initialize cpuinfo structure. * * Arrange pcb, idle stack and interrupt stack in the same * way as is done for the boot CPU in pmap.c. */ cpi->ci_next = NULL; cpi->ci_curproc = NULL; cpi->ci_number = ncpus++; cpi->ci_upaid = portid; cpi->ci_fpproc = NULL; #ifdef MULTIPROCESSOR cpi->ci_spinup = cpu_hatch; /* XXX */ #else cpi->ci_spinup = NULL; #endif cpi->ci_initstack = cpi; cpi->ci_paddr = pa0; #ifdef SUN4V cpi->ci_mmfsa = pa0; #endif cpi->ci_self = cpi; cpi->ci_node = ma->ma_node; sched_init_cpu(cpi); /* * Finally, add itself to the list of active cpus. */ for (ci = cpus; ci->ci_next != NULL; ci = ci->ci_next) ; ci->ci_next = cpi; return (cpi); }