void pccbb_attach_hook(struct device *parent, struct device *self, struct pci_attach_args *pa) { pci_chipset_tag_t pc = pa->pa_pc; int node = PCITAG_NODE(pa->pa_tag); int bus, busrange[2]; if (OF_getprop(OF_parent(node), "bus-range", &busrange, sizeof(busrange)) != sizeof(busrange)) return; bus = busrange[0] + 1; while (bus < 256 && pc->busnode[bus]) bus++; if (bus == 256) return; pc->busnode[bus] = node; }
int ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg, int regsz, void *pintr, int pintrsz, void *mintr, int mintrsz, phandle_t *iparent, void *maskbuf) { int rv; if (ii->opi_imapsz <= 0) return (0); KASSERT(regsz >= ii->opi_addrc, ("ofw_bus_lookup_imap: register size too small: %d < %d", regsz, ii->opi_addrc)); rv = OF_getprop(node, "reg", reg, regsz); if (rv < regsz) panic("ofw_bus_lookup_imap: could not get reg property"); return (ofw_bus_search_intrmap(pintr, pintrsz, reg, ii->opi_addrc, ii->opi_imap, ii->opi_imapsz, ii->opi_imapmsk, maskbuf, mintr, mintrsz, iparent)); }
static int powermac_smp_next_cpu(platform_t plat, struct cpuref *cpuref) { char buf[8]; phandle_t cpu; int res; cpu = OF_peer(cpuref->cr_hwref); while (cpu != 0) { res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); if (res > 0 && strcmp(buf, "cpu") == 0) break; cpu = OF_peer(cpu); } if (cpu == 0) return (ENOENT); return (powermac_smp_fill_cpuref(cpuref, cpu)); }
static int powermac_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) { cell_t cpuid, res; cpuref->cr_hwref = cpu; res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); /* * psim doesn't have a reg property, so assume 0 as for the * uniprocessor case in the CHRP spec. */ if (res < 0) { cpuid = 0; } cpuref->cr_cpuid = cpuid & 0xff; return (0); }
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 int openpicbus_mambo_attach(device_t dev) { uint64_t picaddr; phandle_t nexus; struct openpicbus_softc *sc; sc = device_get_softc(dev); nexus = OF_parent(ofw_bus_get_node(dev)); OF_getprop(nexus,"platform-open-pic", &picaddr,sizeof(picaddr)); sc->picaddr = picaddr; device_add_child(dev,"openpic",-1); return (bus_generic_attach(dev)); }
int fdt_regsize(phandle_t node, u_long *base, u_long *size) { pcell_t reg[4]; int addr_cells, len, size_cells; if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells)) return (ENXIO); if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg)) return (ENOMEM); len = OF_getprop(node, "reg", ®, sizeof(reg)); if (len <= 0) return (EINVAL); *base = fdt_data_get(®[0], addr_cells); *size = fdt_data_get(®[addr_cells], size_cells); return (0); }
int prtc_gettime(todr_chip_handle_t handle, struct timeval *tv) { u_int32_t tod = 0; char buf[32]; if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && strcmp(buf, "SUNW,SPARC-Enterprise") == 0) { tv->tv_sec = prom_opl_get_tod(); tv->tv_usec = 0; return (0); } snprintf(buf, sizeof(buf), "h# %08lx unix-gettod", (long)&tod); OF_interpret(buf, 0); tv->tv_sec = tod; tv->tv_usec = 0; return (0); }
/* * Debugging code to print the entire OFW device tree. */ void oskit_linux_ofw_nodedump(int phandle, int level) { int child, i; char name[32]; for (i = 0; i < level; i++) printk(" "); if (OF_getprop(phandle, "name", name, sizeof(name)) > 0) { printk("0x%x:%s\n", phandle, name); } else { printk("0x%x:????", phandle); } for (child = OF_child(phandle); child; child = OF_peer(child)) { oskit_linux_ofw_nodedump(child, level + 1); } }
oskit_addr_t ofw_getcleaninfo(void) { int cpu; oskit_addr_t vclean, pclean; if ((cpu = OF_finddevice("/cpu")) == -1) panic("ofw_getcleaninfo: OF_finddevice(/cpu)"); if ((OF_getprop(cpu, "d-cache-flush-address", &vclean, sizeof(vclean))) != sizeof(vclean)) return -1; vclean = OF_decode_int((unsigned char *)&vclean); if ((pclean = ofw_gettranslation(vclean)) == -1) panic("ofw_getcleaninfo: ofw_gettranslation(0x%x)", vclean); return pclean; }
uint32_t fman_get_clock(struct fman_softc *sc) { device_t dev; phandle_t node; pcell_t fman_clock; dev = sc->sc_base.dev; node = ofw_bus_get_node(dev); if ((OF_getprop(node, "clock-frequency", &fman_clock, sizeof(fman_clock)) <= 0) || (fman_clock == 0)) { device_printf(dev, "could not acquire correct frequency " "from DTS\n"); return (0); } return ((uint32_t)fman_clock); }
int hfs_open(char *path, struct open_file *f) { int chosen; char bootpath[128], *cp; if ((chosen = OF_finddevice("/chosen")) == -1) return ENXIO; bzero(bootpath, sizeof bootpath); OF_getprop(chosen, "bootpath", bootpath, sizeof bootpath); cp = strrchr(bootpath, ','); if (cp == NULL) return ENXIO; strlcpy(cp + 1, path, bootpath + sizeof bootpath - (cp + 1)); OF_fd = OF_open(bootpath); if (OF_fd == -1) return ENOENT; return 0; }
/* * Determine which channel of a SCC a device referenced by a full device * path or as an alias is (in the latter case we try to look up the device * path via the /aliases node). * Only the device paths of devices which are used for TTYs really allow * to do this as they look like these (taken from /aliases nodes): * ttya: '/central/fhc/zs@0,902000:a' * ttyc: '/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a' * Additionally, for device paths of SCCs which are connected to a RSC * (Remote System Control) device we can hardcode the appropriate channel. * Such device paths look like these: * rsc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' * ttyc: '/pci@1f,4000/ebus@1/se@14,200000:ssp' */ static int uart_cpu_channel(char *dev) { char alias[64]; phandle_t aliases; int len; const char *p; strcpy(alias, dev); if ((aliases = OF_finddevice("/aliases")) != -1) (void)OF_getprop(aliases, dev, alias, sizeof(alias)); len = strlen(alias); if ((p = strrchr(alias, ':')) == NULL) return (0); p++; if (p - alias == len - 1 && (*p == 'a' || *p == 'b')) return (*p - 'a' + 1); if (strcmp(p, "ssp") == 0) return (1); return (0); }
static void get_ncpus(void) { #ifdef MULTIPROCESSOR int node; char sbuf[32]; node = findroot(); sparc_ncpus = 0; for (node = OF_child(node); node; node = OF_peer(node)) { if (OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) <= 0) continue; if (strcmp(sbuf, "cpu") != 0) continue; sparc_ncpus++; } #else sparc_ncpus = 1; #endif }
/* * Get the package handle of the UART that is selected as the console, if * the console is an UART of course. Note that we enforce that both input * and output are selected. * Note that the currently active console (i.e. /chosen/stdout and * /chosen/stdin) may not be the same as the device selected in the * environment (ie /options/output-device and /options/input-device) because * keyboard and screen were selected but the keyboard was unplugged or the * user has changed the environment. In the latter case I would assume that * the user expects that FreeBSD uses the new console setting. * For weirder configurations, use ofw_console(4). */ static phandle_t uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz) { char buf[sizeof("serial")]; ihandle_t inst; phandle_t chosen, input, output; if (OF_getprop(options, "input-device", dev, devsz) == -1) return (-1); input = OF_finddevice(dev); if (OF_getprop(options, "output-device", dev, devsz) == -1) return (-1); output = OF_finddevice(dev); if (input == -1 || output == -1 || OF_getproplen(input, "keyboard") >= 0) { if ((chosen = OF_finddevice("/chosen")) == -1) return (-1); if (OF_getprop(chosen, "stdin", &inst, sizeof(inst)) == -1) return (-1); if ((input = OF_instance_to_package(inst)) == -1) return (-1); if (OF_getprop(chosen, "stdout", &inst, sizeof(inst)) == -1) return (-1); if ((output = OF_instance_to_package(inst)) == -1) return (-1); snprintf(dev, devsz, "ttya"); } if (input != output) return (-1); if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (-1); if (strcmp(buf, "serial") != 0) return (-1); /* For a Serengeti console device point to the bootbus controller. */ if (OF_getprop(input, "name", buf, sizeof(buf)) > 0 && !strcmp(buf, "sgcn")) { if ((chosen = OF_finddevice("/chosen")) == -1) return (-1); if (OF_getprop(chosen, "iosram", &input, sizeof(input)) == -1) return (-1); } return (input); }
static int nvbl_probe(device_t dev) { char control[8]; phandle_t handle; handle = OF_finddevice("mac-io/backlight"); if (handle == -1) return (ENXIO); if (OF_getprop(handle, "backlight-control", &control, sizeof(control)) < 0) return (ENXIO); if (strcmp(control, "mnca") != 0) return (ENXIO); device_set_desc(dev, "PowerBook backlight for nVidia graphics"); return (0); }
void cpu_reset(void) { phandle_t src; uint32_t addr, paddr; bus_addr_t vaddr; if (src_swreset() == 0) goto end; src = OF_finddevice("src"); if ((src != 0) && (OF_getprop(src, "reg", &paddr, sizeof(paddr))) > 0) { addr = fdt32_to_cpu(paddr); if (bus_space_map(fdtbus_bs_tag, addr, 0x10, 0, &vaddr) == 0) { bus_space_write_4(fdtbus_bs_tag, vaddr, 0x00, SW_RST); } } end: while (1); }
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); } }
void copy_disp_props(struct device *dev, int node, prop_dictionary_t dict) { uint32_t temp; char typestr[32]; memset(typestr, 0, sizeof(typestr)); OF_getprop(console_node, "device_type", typestr, sizeof(typestr)); if (strcmp(typestr, "serial") != 0) { /* this is our console, when we don't have a serial console */ prop_dictionary_set_bool(dict, "is_console", 1); } if (!of_to_uint32_prop(dict, node, "width", "width")) { OF_interpret("screen-width", 0, 1, &temp); prop_dictionary_set_uint32(dict, "width", temp); } if (!of_to_uint32_prop(dict, node, "height", "height")) { OF_interpret("screen-height", 0, 1, &temp); prop_dictionary_set_uint32(dict, "height", temp); } of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } if (!of_to_uint32_prop(dict, node, "address", "address")) { uint32_t fbaddr = 0; OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); if (fbaddr != 0) prop_dictionary_set_uint32(dict, "address", fbaddr); } }
void socpcic_mainbus_attach(struct device *parent, struct device *self, void *aux) { struct socpcic_softc *sc = (void *)self; struct mainbus_attach_args *ma = aux; int reg[4]; if (OF_getprop(ma->ma_node, "reg", ®, sizeof(reg)) < sizeof(reg)) { printf(": missing registers\n"); return; } sc->sc_iot = ma->ma_iot; if (bus_space_map(sc->sc_iot, reg[2], 16, 0, &sc->sc_cfg_ioh)) { printf(": can't map configuration registers\n"); return; } sc->sc_node = ma->ma_node; sc->sc_dmat = ma->ma_dmat; socpcic_attach(sc); }
void com_mainbus_attach(device_t parent, device_t self, void *aux) { struct com_mainbus_softc *msc = device_private(self); struct com_softc *sc = &msc->sc_com; int serial, interrupt_length; int interrupts[8]; bus_space_tag_t iot; bus_space_handle_t ioh; bus_addr_t iobase; sc->sc_dev = self; serial = OF_finddevice("/ht@0/isa@4/serial@0x3f8"); if (serial != -1) { interrupt_length = OF_getprop(serial, "interrupts", interrupts, sizeof(interrupts)); } iot = (bus_space_tag_t)0xf4000000; iobase = 0x3f8; comcnattach(iot, iobase, 9600, 1843200, COM_TYPE_NORMAL, (CREAD | CS8)); bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh); COM_INIT_REGS(sc->sc_regs, iot, ioh, iobase); sc->sc_frequency = 1843200; com_attach_subr(sc); #if 1 msc->sc_ih = intr_establish(interrupts[0], IST_LEVEL, IPL_SERIAL, comintr, sc); if (msc->sc_ih == NULL) panic("failed to establish int handler"); #endif }
static int powermac_probe(platform_t plat) { char compat[255]; ssize_t compatlen; char *curstr; phandle_t root; root = OF_peer(0); if (root == 0) return (ENXIO); compatlen = OF_getprop(root, "compatible", compat, sizeof(compat)); for (curstr = compat; curstr < compat + compatlen; curstr += strlen(curstr) + 1) { if (strncmp(curstr, "MacRISC", 7) == 0) return (BUS_PROBE_SPECIFIC); } return (ENXIO); }
uint64_t memsize(void) { phandle_t memoryp; cell_t reg[24]; int i, sz; u_int64_t memsz; memsz = 0; memoryp = OF_instance_to_package(memory); sz = OF_getprop(memoryp, "reg", ®, sizeof(reg)); sz /= sizeof(reg[0]); for (i = 0; i < sz; i += (acells + scells)) { if (scells > 1) memsz += (uint64_t)reg[i + acells] << 32; memsz += reg[i + acells + scells - 1]; } return (memsz); }
static void cn_drvinit(void *unused) { phandle_t options; char output[32]; struct tty *tp; if (ofw_consdev.cn_pri != CN_DEAD && ofw_consdev.cn_name[0] != '\0') { if ((options = OF_finddevice("/options")) == -1 || OF_getprop(options, "output-device", output, sizeof(output)) == -1) return; /* * XXX: This is a hack and it may result in two /dev/ttya * XXX: devices on platforms where the sab driver works. */ tp = tty_alloc(&ofw_ttydevsw, NULL); tty_makedev(tp, NULL, "%s", output); tty_makealias(tp, "ofwcons"); } }
/* * Hunt through the device tree for CPUs. There should be no need to * go more than four levels deep; an UltraSPARC-IV on Seregeti shows * up as /ssm@0,0/cmp@0,0/cpu@0 and a SPARC64-VI will show up as * /cmp@0,0/core@0/cpu@0. */ int get_ncpus(void) { #ifdef MULTIPROCESSOR int node, child, stack[4], depth, ncpus; char buf[32]; stack[0] = findroot(); depth = 0; ncpus = 0; for (;;) { node = stack[depth]; if (node == 0 || node == -1) { if (--depth < 0) return (ncpus); stack[depth] = OF_peer(stack[depth]); continue; } if (OF_getprop(node, "device_type", buf, sizeof(buf)) > 0 && strcmp(buf, "cpu") == 0) ncpus++; child = OF_child(node); if (child != 0 && child != -1 && depth < 3) stack[++depth] = child; else stack[depth] = OF_peer(stack[depth]); } return (0); #else return (1); #endif }
static int copy_rom_font() { u_char *romfont; int char_width, char_height; int chosen, mmu, m, e; /* Get ROM FONT address. */ OF_interpret("font-adr", 0, 1, &romfont); if (romfont == NULL) return -1; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "mmu", &mmu, 4); /* * Convert to physcal address. We cannot access to Open Firmware's * virtual address space. */ OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e); /* Get character size */ OF_interpret("char-width", 0, 1, &char_width); OF_interpret("char-height", 0, 1, &char_height); openfirm6x11.name = "Open Firmware"; openfirm6x11.firstchar = 32; openfirm6x11.numchars = 96; openfirm6x11.encoding = WSDISPLAY_FONTENC_ISO; openfirm6x11.fontwidth = char_width; openfirm6x11.fontheight = char_height; openfirm6x11.stride = 1; openfirm6x11.bitorder = WSDISPLAY_FONTORDER_L2R; openfirm6x11.byteorder = WSDISPLAY_FONTORDER_L2R; openfirm6x11.data = romfont; return 0; }
void macppc_pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) { pci_chipset_tag_t pc = pba->pba_pc; int bus = pba->pba_bus; int node, nn, sz; int32_t busrange[2]; for (node = pc->pc_node; node; node = nn) { sz = OF_getprop(node, "bus-range", busrange, 8); if (sz == 8 && busrange[0] == bus) { fixpci(node, pc); return; } if ((nn = OF_child(node)) != 0) continue; while ((nn = OF_peer(node)) == 0) { node = OF_parent(node); if (node == pc->pc_node) return; /* not found */ } } }
void ki2c_attach_bus(struct ki2c_softc *sc, struct ki2c_bus *bus, int node) { struct i2cbus_attach_args iba; u_int32_t reg; if (OF_getprop(node, "reg", ®, sizeof reg) != sizeof reg) return; bus->sc = sc; bus->i2c_tag.ic_cookie = bus; bus->i2c_tag.ic_acquire_bus = ki2c_i2c_acquire_bus; bus->i2c_tag.ic_release_bus = ki2c_i2c_release_bus; bus->i2c_tag.ic_exec = ki2c_i2c_exec; bus->reg = reg; bzero(&iba, sizeof iba); iba.iba_name = "iic"; iba.iba_tag = &bus->i2c_tag; iba.iba_bus_scan = maciic_scan; iba.iba_bus_scan_arg = &node; config_found(&sc->sc_dev, &iba, NULL); }
int wdc_obio_probe(struct device *parent, void *match, void *aux) { struct confargs *ca = aux; char compat[32]; if (ca->ca_nreg < 8) return 0; /* XXX should not use name */ if (strcmp(ca->ca_name, "ATA") == 0 || strncmp(ca->ca_name, "ata", 3) == 0 || strcmp(ca->ca_name, "ide") == 0) return 1; bzero(compat, sizeof(compat)); OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat)); if (strcmp(compat, "heathrow-ata") == 0 || strcmp(compat, "keylargo-ata") == 0) return 1; return 0; }
static int ofnet_match(struct device *parent, struct cfdata *match, void *aux) { struct ofbus_attach_args *oba = aux; char type[32]; int l; #if NIPKDB_OFN > 0 if (!parent) return ipkdbprobe(match, aux); #endif if (strcmp(oba->oba_busname, "ofw")) return (0); if ((l = OF_getprop(oba->oba_phandle, "device_type", type, sizeof type - 1)) < 0) return 0; if (l >= sizeof type) return 0; type[l] = 0; if (strcmp(type, "network")) return 0; return 1; }