vt_efb_initialize(struct fb_info *info) #endif { #ifdef FDT char name[64]; cell_t retval; ihandle_t ih; int i; /* Open display device, thereby initializing it */ memset(name, 0, sizeof(name)); OF_package_to_path(node, name, sizeof(name)); ih = OF_open(name); #endif /* * Set up the color map */ switch (info->fb_depth) { case 8: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0); break; case 15: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0); break; case 16: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0); break; case 24: case 32: #if BYTE_ORDER == BIG_ENDIAN vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); #else vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); #endif #ifdef FDT for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, (cell_t)((info->fb_cmap[i] >> 16) & 0xff), (cell_t)((info->fb_cmap[i] >> 8) & 0xff), (cell_t)((info->fb_cmap[i] >> 0) & 0xff), (cell_t)i, &retval); } #endif break; default: panic("Unknown color space fb_depth %d", info->fb_depth); break; } }
/* Return the fully qualified pathname corresponding to an instance. */ static ssize_t ofw_fdt_instance_to_path(ofw_t ofw, ihandle_t instance, char *buf, size_t len) { phandle_t phandle; phandle = OF_instance_to_package(instance); if (phandle == -1) return (-1); return (OF_package_to_path(phandle, buf, len)); }
static void ofnet_attach(struct device *parent, struct device *self, void *aux) { struct ofnet_softc *of = device_private(self); struct ifnet *ifp = &of->sc_ethercom.ec_if; struct ofbus_attach_args *oba = aux; char path[256]; int l; u_int8_t myaddr[ETHER_ADDR_LEN]; of->sc_phandle = oba->oba_phandle; #if NIPKDB_OFN > 0 if (kifp && kifp->unit - 1 == device_unit(&of->sc_dev) && OF_instance_to_package(kifp->port) == oba->oba_phandle) { ipkdb_of = of; of->sc_ihandle = kifp->port; } else #endif if ((l = OF_package_to_path(oba->oba_phandle, path, sizeof path - 1)) < 0 || l >= sizeof path || (path[l] = 0, !(of->sc_ihandle = OF_open(path)))) panic("ofnet_attach: unable to open"); if (OF_getprop(oba->oba_phandle, "mac-address", myaddr, sizeof myaddr) < 0) panic("ofnet_attach: no mac-address"); printf(": address %s\n", ether_sprintf(myaddr)); callout_init(&of->sc_callout, 0); strlcpy(ifp->if_xname, device_xname(&of->sc_dev), IFNAMSIZ); ifp->if_softc = of; ifp->if_start = ofnet_start; ifp->if_ioctl = ofnet_ioctl; ifp->if_watchdog = ofnet_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; IFQ_SET_READY(&ifp->if_snd); if_attach(ifp); ether_ifattach(ifp, myaddr); }
static void fix_cardbus_bridge(int node, pci_chipset_tag_t pc, pcitag_t tag) { uint32_t bus_number = 0xffffffff; pcireg_t bi; int bus, dev, fn, ih, len; char path[256]; #if PB3400_CARDBUS_HACK int root_node; root_node = OF_finddevice("/"); if (of_compatible(root_node, pb3400_compat) != -1) { bus_number = cardbus_number; cardbus_number++; } else { #endif ih = OF_open(path); OF_call_method("load-ata", ih, 0, 0); OF_close(ih); OF_getprop(node, "AAPL,bus-id", &bus_number, sizeof(bus_number)); #if PB3400_CARDBUS_HACK } #endif if (bus_number != 0xffffffff) { len = OF_package_to_path(node, path, sizeof(path)); path[len] = 0; aprint_verbose("\n%s: fixing bus number to %d", path, bus_number); pci_decompose_tag(pc, tag, &bus, &dev, &fn); bi = pci_conf_read(pc, tag, PPB_REG_BUSINFO); bi &= 0xff000000; /* XXX subordinate is always 32 here */ bi |= (bus & 0xff) | (bus_number << 8) | 0x200000; pci_conf_write(pc, tag, PPB_REG_BUSINFO, bi); } }
static int ofwfb_set_mode(video_adapter_t *adp, int mode) { struct ofwfb_softc *sc; char name[64]; ihandle_t ih; int i, retval; sc = (struct ofwfb_softc *)adp; if (ofwfb_reset_on_switch) { /* * Open the display device, which will initialize it. */ memset(name, 0, sizeof(name)); OF_package_to_path(sc->sc_node, name, sizeof(name)); ih = OF_open(name); if (sc->sc_depth == 8) { /* * Install the ISO6429 colormap - older OFW systems * don't do this by default */ for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, ofwfb_cmap[i].red, ofwfb_cmap[i].green, ofwfb_cmap[i].blue, i, &retval); } } } ofwfb_blank_display(&sc->sc_va, V_DISPLAY_ON); return (0); }
static void rtas_setup(void *junk) { ihandle_t rtasi; cell_t rtas_size = 0, rtas_ptr; char path[31]; int result; rtas = OF_finddevice("/rtas"); if (rtas == -1) { rtas = 0; return; } OF_package_to_path(rtas, path, sizeof(path)); rtasi = OF_open(path); if (rtasi == 0) { rtas = 0; printf("Error initializing RTAS: could not open node\n"); return; } mtx_init(&rtas_mtx, "RTAS", MTX_DEF, 0); /* RTAS must be called with everything turned off in MSR */ rtasmsr = mfmsr(); rtasmsr &= ~(PSL_IR | PSL_DR | PSL_EE | PSL_SE); #ifdef __powerpc64__ rtasmsr &= ~PSL_SF; #endif /* * Allocate rtas_size + one page of contiguous, wired physical memory * that can fit into a 32-bit address space and accessed from real mode. * This is used both to bounce arguments and for RTAS private data. * * It must be 4KB-aligned and not cross a 256 MB boundary. */ OF_getprop(rtas, "rtas-size", &rtas_size, sizeof(rtas_size)); rtas_size = round_page(rtas_size); rtas_bounce_virt = contigmalloc(rtas_size + PAGE_SIZE, M_RTAS, 0, 0, ulmin(platform_real_maxaddr(), BUS_SPACE_MAXADDR_32BIT), 4096, 256*1024*1024); rtas_private_data = vtophys(rtas_bounce_virt); rtas_bounce_virt += rtas_size; /* Actual bounce area */ rtas_bounce_phys = vtophys(rtas_bounce_virt); rtas_bounce_size = PAGE_SIZE; /* * Instantiate RTAS. We always use the 32-bit version. */ result = OF_call_method("instantiate-rtas", rtasi, 1, 1, (cell_t)rtas_private_data, &rtas_ptr); OF_close(rtasi); if (result != 0) { rtas = 0; rtas_ptr = 0; printf("Error initializing RTAS (%d)\n", result); return; } rtas_entry = (uintptr_t)(rtas_ptr); }
static void ofwpci_attach(device_t parent, device_t self, void *aux) { struct ofwpci_softc *sc = device_private(self); pci_chipset_tag_t pc = &sc->sc_pc; struct confargs *ca = aux; struct pcibus_attach_args pba; struct genppc_pci_chipset_businfo *pbi; int node = ca->ca_node; int i, isprim = 0; uint32_t busrange[2]; char buf[64]; #ifdef PCI_NETBSD_CONFIGURE struct extent *ioext, *memext; #endif aprint_normal("\n"); sc->sc_dev = self; /* PCI bus number */ if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) return; /* bus space map the io ranges */ sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE; sc->sc_iot.pbs_base = 0x00000000; if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot, "ofwpci io-space") != 0) panic("Can't init ofwpci 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, "ofwpci mem-space") != 0) panic("Can't init ofwpci mem tag"); aprint_debug("io base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_iot.pbs_base, sc->sc_iot.pbs_offset, sc->sc_iot.pbs_limit); aprint_debug("mem base=0x%"PRIxPTR" offset=0x%"PRIxPTR" limit=0x%"PRIxPTR"\n", sc->sc_memt.pbs_base, sc->sc_memt.pbs_offset, sc->sc_memt.pbs_limit); /* are we the primary pci bus? */ if (of_find_firstchild_byname(OF_finddevice("/"), "pci") == node) { int isa_node; isprim++; /* yes we are, now do we have an ISA child? */ isa_node = of_find_firstchild_byname(node, "isa"); if (isa_node != -1) { /* isa == pci */ genppc_isa_io_space_tag = sc->sc_iot; genppc_isa_mem_space_tag = sc->sc_memt; map_isa_ioregs(); init_ofppc_interrupt(); ofppc_init_comcons(isa_node); } } ofwpci_get_chipset_tag(pc); pc->pc_node = node; i = OF_package_to_path(node, buf, sizeof(buf)-5); if (i <= 0) panic("Can't determine path for pci node %d", node); buf[i] = '\0'; pc->pc_ihandle = OF_open(buf); if (pc->pc_ihandle < 0) panic("Can't open device %s", buf); pc->pc_bus = busrange[0]; pc->pc_iot = &sc->sc_iot; pc->pc_memt = &sc->sc_memt; pbi = malloc(sizeof(struct genppc_pci_chipset_businfo), M_DEVBUF, M_NOWAIT); KASSERT(pbi != NULL); pbi->pbi_properties = prop_dictionary_create(); KASSERT(pbi->pbi_properties != NULL); SIMPLEQ_INIT(&pc->pc_pbi); SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next); genofw_setup_pciintr_map((void *)pc, pbi, pc->pc_node); #ifdef PCI_NETBSD_CONFIGURE ioext = extent_create("pciio", modeldata.pciiodata[device_unit(self)].start, modeldata.pciiodata[device_unit(self)].limit, NULL, 0, EX_NOWAIT); memext = extent_create("pcimem", sc->sc_memt.pbs_base, sc->sc_memt.pbs_limit-1, NULL, 0, EX_NOWAIT); if (pci_configure_bus(pc, ioext, memext, NULL, 0, CACHELINESIZE)) aprint_error("pci_configure_bus() failed\n"); extent_destroy(ioext); extent_destroy(memext); #endif /* PCI_NETBSD_CONFIGURE */ 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); }
int ofdisk_open(dev_t dev, int flags, int fmt, struct lwp *lwp) { struct ofdisk_softc *of; char path[256]; int error, l, part; of = device_lookup_private(&ofdisk_cd, DISKUNIT(dev)); if (of == NULL) return ENXIO; part = DISKPART(dev); mutex_enter(&of->sc_dk.dk_openlock); /* * If there are wedges, and this is not RAW_PART, then we * need to fail. */ if (of->sc_dk.dk_nwedges != 0 && part != RAW_PART) { error = EBUSY; goto bad1; } if (!of->sc_ihandle) { if ((l = OF_package_to_path(of->sc_phandle, path, sizeof path - 3)) < 0 || l >= sizeof path - 3) { error = ENXIO; goto bad1; } path[l] = 0; /* * XXX This is for the benefit of SCSI/IDE disks that don't * XXX have all their childs in the device tree. * XXX YES, I DO THINK THIS IS A BUG IN OPENFIRMWARE!!! * XXX And yes, this is a very gross hack! * XXX See also ofscsi.c */ if (!strcmp(path + l - 4, "disk")) { path[l++] = '@'; path[l++] = '0' + of->sc_unit; path[l] = 0; } strlcat(path, ":0", sizeof(path)); if ((of->sc_ihandle = OF_open(path)) == -1) { error = ENXIO; goto bad1; } /* * Try to get characteristics of the disk. */ of->max_transfer = OF_call_method_1("max-transfer", of->sc_ihandle, 0); if (of->max_transfer > MAXPHYS) of->max_transfer = MAXPHYS; ofdisk_getdisklabel(dev); } switch (fmt) { case S_IFCHR: of->sc_dk.dk_copenmask |= 1 << part; break; case S_IFBLK: of->sc_dk.dk_bopenmask |= 1 << part; break; } of->sc_dk.dk_openmask = of->sc_dk.dk_copenmask | of->sc_dk.dk_bopenmask; error = 0; bad1: mutex_exit(&of->sc_dk.dk_openlock); return (error); }
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->sc_if; struct mii_data *mii = &sc->sc_mii; u_char laddr[6]; callout_init(&sc->sc_tick_ch, 0); sc->sc_flags =0; if (strcmp(ca->ca_name, "ethernet") == 0) { char name[64]; memset(name, 0, 64); OF_package_to_path(ca->ca_node, name, sizeof(name)); OF_open(name); 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_iot = ca->ca_tag; if (bus_space_map(sc->sc_iot, ca->ca_reg[0], ca->ca_reg[1], 0, &sc->sc_ioh) != 0) { aprint_error(": couldn't map %#x", ca->ca_reg[0]); return; } 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; } memcpy(sc->sc_enaddr, laddr, 6); sc->sc_txdma = mapiodev(ca->ca_reg[2], PAGE_SIZE); sc->sc_rxdma = mapiodev(ca->ca_reg[4], PAGE_SIZE); sc->sc_txcmd = dbdma_alloc(BMAC_TXBUFS * sizeof(dbdma_command_t)); sc->sc_rxcmd = dbdma_alloc((BMAC_RXBUFS + 1) * sizeof(dbdma_command_t)); sc->sc_txbuf = malloc(BMAC_BUFLEN * BMAC_TXBUFS, M_DEVBUF, M_NOWAIT); sc->sc_rxbuf = malloc(BMAC_BUFLEN * BMAC_RXBUFS, M_DEVBUF, M_NOWAIT); if (sc->sc_txbuf == NULL || sc->sc_rxbuf == NULL || sc->sc_txcmd == NULL || sc->sc_rxcmd == NULL) { printf("cannot allocate memory\n"); return; } printf(" irq %d,%d: address %s\n", ca->ca_intr[0], ca->ca_intr[2], ether_sprintf(laddr)); intr_establish(ca->ca_intr[0], IST_EDGE, IPL_NET, bmac_intr, sc); intr_establish(ca->ca_intr[2], IST_EDGE, IPL_NET, bmac_rint, sc); memcpy(ifp->if_xname, sc->sc_dev.dv_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; sc->sc_ethercom.ec_mii = mii; ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_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, sc->sc_enaddr); }
void wdc_obio_attach(device_t parent, device_t self, void *aux) { struct wdc_obio_softc *sc = device_private(self); struct wdc_regs *wdr; struct confargs *ca = aux; struct ata_channel *chp = &sc->sc_channel; int intr, i, type = IST_EDGE; int use_dma = 0; char path[80]; sc->sc_wdcdev.sc_atac.atac_dev = self; if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags & WDC_OPTIONS_DMA) { if (ca->ca_nreg >= 16 || ca->ca_nintr == -1) use_dma = 1; /* XXX Don't work yet. */ } if (ca->ca_nintr >= 4 && ca->ca_nreg >= 8) { intr = ca->ca_intr[0]; aprint_normal(" irq %d", intr); if (ca->ca_nintr > 8) { type = ca->ca_intr[1] ? IST_LEVEL : IST_EDGE; } aprint_normal(", %s triggered", (type == IST_EDGE) ? "edge" : "level"); } else if (ca->ca_nintr == -1) { intr = WDC_DEFAULT_PIO_IRQ; aprint_normal(" irq property not found; using %d", intr); } else { aprint_error(": couldn't get irq property\n"); return; } if (use_dma) aprint_normal(": DMA transfer"); aprint_normal("\n"); sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs; wdr->cmd_iot = wdr->ctl_iot = ca->ca_tag; if (bus_space_map(wdr->cmd_iot, ca->ca_baseaddr + ca->ca_reg[0], WDC_REG_NPORTS << 4, 0, &wdr->cmd_baseioh) || bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, WDC_AUXREG_OFFSET << 4, 1, &wdr->ctl_ioh)) { aprint_error_dev(self, "couldn't map registers\n"); return; } for (i = 0; i < WDC_NREG; i++) { if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, i << 4, i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) { bus_space_unmap(wdr->cmd_iot, wdr->cmd_baseioh, WDC_REG_NPORTS << 4); aprint_error_dev(self, "couldn't subregion registers\n"); return; } } #if 0 wdr->data32iot = wdr->cmd_iot; wdr->data32ioh = wdr->cmd_ioh; #endif sc->sc_ih = intr_establish(intr, type, IPL_BIO, wdcintr, chp); if (use_dma) { sc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20); /* * XXX * we don't use ca->ca_reg[3] for size here because at least * on the PB3400c it says 0x200 for both IDE channels ( the * one on the mainboard and the other on the mediabay ) but * their start addresses are only 0x100 apart. Since those * DMA registers are always 0x100 or less we don't really * have to care though */ if (bus_space_map(wdr->cmd_iot, ca->ca_baseaddr + ca->ca_reg[2], 0x100, BUS_SPACE_MAP_LINEAR, &sc->sc_dmaregh)) { aprint_error_dev(self, "unable to map DMA registers (%08x)\n", ca->ca_reg[2]); /* should unmap stuff here */ return; } sc->sc_dmareg = bus_space_vaddr(wdr->cmd_iot, sc->sc_dmaregh); sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA; sc->sc_wdcdev.sc_atac.atac_dma_cap = 2; if (strcmp(ca->ca_name, "ata-4") == 0) { sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_UDMA; sc->sc_wdcdev.sc_atac.atac_udma_cap = 4; sc->sc_wdcdev.sc_atac.atac_set_modes = ata4_adjust_timing; } else { sc->sc_wdcdev.sc_atac.atac_set_modes = adjust_timing; } #ifdef notyet /* Minimum cycle time is 150ns (DMA MODE 1) on ohare. */ if (ohare) { sc->sc_wdcdev.sc_atac.atac_pio_cap = 3; sc->sc_wdcdev.sc_atac.atac_dma_cap = 1; } #endif } else { /* all non-DMA controllers can use adjust_timing */ sc->sc_wdcdev.sc_atac.atac_set_modes = adjust_timing; } sc->sc_wdcdev.sc_atac.atac_pio_cap = 4; sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16; sc->sc_chanptr = chp; sc->sc_wdcdev.sc_atac.atac_channels = &sc->sc_chanptr; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; sc->sc_wdcdev.wdc_maxdrives = 2; 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->ch_channel = 0; chp->ch_atac = &sc->sc_wdcdev.sc_atac; chp->ch_queue = &sc->sc_chqueue; wdc_init_shadow_regs(chp); #define OHARE_FEATURE_REG 0xf3000038 /* XXX Enable wdc1 by feature reg. */ memset(path, 0, sizeof(path)); OF_package_to_path(ca->ca_node, path, sizeof(path)); if (strcmp(path, "/bandit@F2000000/ohare@10/ata@21000") == 0) { u_int x; x = in32rb(OHARE_FEATURE_REG); x |= 8; out32rb(OHARE_FEATURE_REG, x); } wdcattach(chp); }