static void ofw_cnprobe(struct consdev *cp) { int chosen; if ((chosen = OF_finddevice("/chosen")) == -1) { cp->cn_pri = CN_DEAD; return; } if (OF_getencprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) { cp->cn_pri = CN_DEAD; return; } if (OF_getencprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) { cp->cn_pri = CN_DEAD; return; } cp->cn_pri = CN_LOW; }
static void fsl_ocotp_devmap(void) { phandle_t child, root; u_long base, size; if ((root = OF_finddevice("/")) == 0) goto fatal; if ((child = fdt_depth_search_compatible(root, "fsl,imx6q-ocotp", 0)) == 0) goto fatal; if (fdt_regsize(child, &base, &size) != 0) goto fatal; ocotp_size = (vm_size_t)size; if ((ocotp_regs = pmap_mapdev((vm_offset_t)base, ocotp_size)) == NULL) goto fatal; return; fatal: panic("cannot find/map the ocotp registers"); }
/* * Get the package handle of the UART that is selected as the keyboard port, * if it's actually used to connect the keyboard according to the OF. I.e. * this will return the UART used to connect the keyboard regardless whether * it's stdin or not, however not in case the user or the OF gave preference * to e.g. a PS/2 keyboard by setting /aliases/keyboard accordingly. */ static phandle_t uart_cpu_getdev_keyboard(char *dev, size_t devsz) { char buf[sizeof("serial")]; phandle_t input; if ((input = OF_finddevice("keyboard")) == -1) return (-1); if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (-1); if (strcmp(buf, "serial") != 0) return (-1); if (OF_getprop(input, "name", dev, devsz) == -1) return (-1); /* * So far this also matched PS/2 keyboard nodes so make sure it's * one of the SCCs/UARTs known to be used to connect keyboards. */ if (strcmp(dev, "su") && strcmp(dev, "su_pnp") && strcmp(dev, "zs")) return (-1); return (input); }
void OF_getetheraddr(device_t dev, u_char *addr) { char buf[sizeof("true")]; phandle_t node; struct idprom idp; if ((node = OF_finddevice("/options")) > 0 && OF_getprop(node, "local-mac-address?", buf, sizeof(buf)) > 0) { buf[sizeof(buf) - 1] = '\0'; if (strcmp(buf, "true") == 0 && (node = ofw_bus_get_node(dev)) > 0 && OF_getprop(node, "local-mac-address", addr, ETHER_ADDR_LEN) == ETHER_ADDR_LEN) return; } node = OF_peer(0); if (node <= 0 || OF_getprop(node, "idprom", &idp, sizeof(idp)) == -1) panic("Could not determine the machine Ethernet address"); bcopy(&idp.id_ether, addr, ETHER_ADDR_LEN); }
static int openpic_ofw_probe(device_t dev) { const char *type = ofw_bus_get_type(dev); if (type == NULL) return (ENXIO); if (!ofw_bus_is_compatible(dev, "chrp,open-pic") && strcmp(type, "open-pic") != 0) return (ENXIO); /* * On some U4 systems, there is a phantom MPIC in the mac-io cell. * The uninorth driver will pick up the real PIC, so ignore it here. */ if (OF_finddevice("/u4") != (phandle_t)-1) return (ENXIO); device_set_desc(dev, OPENPIC_DEVSTR); return (0); }
static int powermac_smp_first_cpu(platform_t plat, struct cpuref *cpuref) { char buf[8]; phandle_t cpu, dev, root; int res; root = OF_peer(0); dev = OF_child(root); while (dev != 0) { res = OF_getprop(dev, "name", buf, sizeof(buf)); if (res > 0 && strcmp(buf, "cpus") == 0) break; dev = OF_peer(dev); } if (dev == 0) { /* * psim doesn't have a name property on the /cpus node, * but it can be found directly */ dev = OF_finddevice("/cpus"); if (dev == -1) return (ENOENT); } cpu = OF_child(dev); 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 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; }
static void uart_phyp_cnprobe(struct consdev *cp) { char buf[64]; ihandle_t stdout; phandle_t input, chosen; static struct uart_phyp_softc sc; if ((chosen = OF_finddevice("/chosen")) == -1) goto fail; /* Check if OF has an active stdin/stdout */ input = -1; if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == sizeof(stdout) && stdout != 0) input = OF_instance_to_package(stdout); if (input == -1) goto fail; if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) goto fail; if (strcmp(buf, "serial") != 0) goto fail; sc.node = input; if (uart_phyp_probe_node(&sc) != 0) goto fail; mtx_init(&sc.sc_mtx, "uart_phyp", NULL, MTX_SPIN | MTX_QUIET | MTX_NOWITNESS); cp->cn_pri = CN_NORMAL; console_sc = ≻ return; fail: cp->cn_pri = CN_DEAD; return; }
static void aml8726_fixup_busfreq(void) { phandle_t node; pcell_t freq, prop; ssize_t len; /* * Set the bus-frequency for the SoC simple-bus if it * needs updating (meaning the current frequency is zero). */ if ((freq = aml8726_clkmsr_bus_frequency()) == 0 || (node = OF_finddevice("/soc")) == 0 || fdt_is_compatible_strict(node, "simple-bus") == 0) while (1); freq = cpu_to_fdt32(freq); len = OF_getencprop(node, "bus-frequency", &prop, sizeof(prop)); if ((len / sizeof(prop)) == 1 && prop == 0) OF_setprop(node, "bus-frequency", (void *)&freq, sizeof(freq)); }
void * ofw_alloc_heap(unsigned int size) { phandle_t memoryp, root; cell_t available[4]; cell_t acells; root = OF_finddevice("/"); acells = 1; OF_getprop(root, "#address-cells", &acells, sizeof(acells)); memoryp = OF_instance_to_package(memory); OF_getprop(memoryp, "available", available, sizeof(available)); heap_base = OF_claim((void *)available[acells-1], size, sizeof(register_t)); if (heap_base != (void *)-1) { heap_size = size; } return (heap_base); }
static void ofw_cons_probe(struct consdev *cp) { int chosen; if ((chosen = OF_finddevice("/chosen")) == -1) { cp->cn_pri = CN_DEAD; return; } if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) { cp->cn_pri = CN_DEAD; return; } if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) { cp->cn_pri = CN_DEAD; return; } cp->cn_dev = NULL; cp->cn_pri = CN_INTERNAL; }
int main() { int chosen; /* * Get the boot arguments from Openfirmware */ if ((chosen = OF_finddevice("/chosen")) == -1 || OF_getprop(chosen, "bootpath", bootdev, sizeof bootdev) < 0 || OF_getprop(chosen, "bootargs", bootline, sizeof bootline) < 0) { printf("Invalid Openfirmware environment\n"); exit(); } prom2boot(bootdev); get_alt_bootdev(bootdev, sizeof(bootdev), bootline, sizeof(bootline)); if (bootline[0] != '\0') kernelfile = bootline; OF_claim((void *)0x00100000, CLAIM_LIMIT, 0); /* XXX */ boot(0); return 0; }
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') { tp = tty_alloc(&ofw_ttydevsw, NULL); tty_makedev(tp, NULL, "%s", "ofwcons"); /* * XXX: This is a hack and it may result in two /dev/ttya * XXX: devices on platforms where the sab driver works. */ if ((options = OF_finddevice("/options")) == -1 || OF_getprop(options, "output-device", output, sizeof(output)) == -1) return; if (strlen(output) > 0) tty_makealias(tp, output); } }
static int l3remap(struct rstmgr_softc *sc, int remap, int enable) { uint32_t addr, paddr; bus_addr_t vaddr; phandle_t node; int reg; /* * Control whether bridge is visible to L3 masters or not. * Register is write-only. */ reg = REMAP_MPUZERO; if (enable) reg |= (remap); else reg &= ~(remap); node = OF_finddevice("l3regs"); if (node == -1) { device_printf(sc->dev, "Can't find l3regs node\n"); return (1); } if ((OF_getprop(node, "reg", &paddr, sizeof(paddr))) > 0) { addr = fdt32_to_cpu(paddr); if (bus_space_map(fdtbus_bs_tag, addr, 0x4, 0, &vaddr) == 0) { bus_space_write_4(fdtbus_bs_tag, vaddr, L3REGS_REMAP, reg); return (0); } } return (1); }
void cpu_reset(void) { uint32_t paddr; bus_addr_t vaddr; phandle_t node; if (rstmgr_warmreset() == 0) goto end; node = OF_finddevice("rstmgr"); if (node == -1) goto end; if ((OF_getencprop(node, "reg", &paddr, sizeof(paddr))) > 0) { if (bus_space_map(fdtbus_bs_tag, paddr, 0x8, 0, &vaddr) == 0) { bus_space_write_4(fdtbus_bs_tag, vaddr, RSTMGR_CTRL, CTRL_SWWARMRSTREQ); } } end: while (1); }
static void pmu_attach(device_t parent, device_t self, void *aux) { struct confargs *ca = aux; struct pmu_softc *sc = device_private(self); #if notyet struct i2cbus_attach_args iba; #endif uint32_t regs[16]; int irq = ca->ca_intr[0]; int node, extint_node, root_node; int nbat = 1, i, pmnode; int type = IST_EDGE; uint8_t cmd[2] = {2, 0}; uint8_t resp[16]; char name[256]; extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1"); if (extint_node) { OF_getprop(extint_node, "interrupts", &irq, 4); type = IST_LEVEL; } aprint_normal(" irq %d: ", irq); sc->sc_dev = self; sc->sc_node = ca->ca_node; sc->sc_memt = ca->ca_tag; root_node = OF_finddevice("/"); sc->sc_error = 0; sc->sc_autopoll = 0; sc->sc_pending_eject = 0; sc->sc_brightness = sc->sc_brightness_wanted = 0x80; sc->sc_volume = sc->sc_volume_wanted = 0x80; sc->sc_flags = 0; sc->sc_callback = NULL; sc->sc_lid_closed = 0; if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr, ca->ca_reg[1], 0, &sc->sc_memh) != 0) { aprint_error_dev(self, "unable to map registers\n"); return; } sc->sc_ih = intr_establish(irq, type, IPL_TTY, pmu_intr, sc); pmu_init(sc); sc->sc_pmu_ops.cookie = sc; sc->sc_pmu_ops.do_command = pmu_send; sc->sc_pmu_ops.register_callback = pmu_register_callback; if (pmu0 == NULL) pmu0 = sc; pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp); /* check what kind of PMU we're talking to */ if (pmu_send(sc, PMU_GET_VERSION, 0, cmd, 16, resp) > 1) aprint_normal(" rev. %d", resp[1]); aprint_normal("\n"); node = OF_child(sc->sc_node); while (node != 0) { if (OF_getprop(node, "name", name, 256) == 0) goto next; if (strncmp(name, "pmu-i2c", 8) == 0) { aprint_normal_dev(self, "initializing IIC bus\n"); goto next; } if (strncmp(name, "adb", 4) == 0) { aprint_normal_dev(self, "initializing ADB\n"); sc->sc_adbops.cookie = sc; sc->sc_adbops.send = pmu_adb_send; sc->sc_adbops.poll = pmu_adb_poll; sc->sc_adbops.autopoll = pmu_autopoll; sc->sc_adbops.set_handler = pmu_adb_set_handler; #if NNADB > 0 config_found_ia(self, "adb_bus", &sc->sc_adbops, nadb_print); #endif goto next; } if (strncmp(name, "rtc", 4) == 0) { aprint_normal_dev(self, "initializing RTC\n"); sc->sc_todr.todr_gettime = pmu_todr_get; sc->sc_todr.todr_settime = pmu_todr_set; sc->sc_todr.cookie = sc; todr_attach(&sc->sc_todr); goto next; } if (strncmp(name, "battery", 8) == 0) goto next; aprint_normal_dev(self, "%s not configured\n", name); next: node = OF_peer(node); } if (OF_finddevice("/bandit/ohare") != -1) { aprint_normal_dev(self, "enabling ohare backlight control\n"); sc->sc_flags |= PMU_HAS_BACKLIGHT_CONTROL; cmd[0] = 0; cmd[1] = 0; memset(resp, 0, 6); if (pmu_send(sc, PMU_READ_BRIGHTNESS, 1, cmd, 16, resp) > 1) { sc->sc_brightness_wanted = resp[1]; pmu_update_brightness(sc); } } /* attach batteries */ if (of_compatible(root_node, has_legacy_battery) != -1) { pmu_attach_legacy_battery(sc); } else if (of_compatible(root_node, has_two_smart_batteries) != -1) { pmu_attach_smart_battery(sc, 0); pmu_attach_smart_battery(sc, 1); } else { /* check how many batteries we have */ pmnode = of_getnode_byname(ca->ca_node, "power-mgt"); if (pmnode == -1) goto bat_done; if (OF_getprop(pmnode, "prim-info", regs, sizeof(regs)) < 24) goto bat_done; nbat = regs[6] >> 16; for (i = 0; i < nbat; i++) pmu_attach_smart_battery(sc, i); } bat_done: #if notyet memset(&iba, 0, sizeof(iba)); iba.iba_tag = &sc->sc_i2c; sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = pmu_i2c_acquire_bus; sc->sc_i2c.ic_release_bus = pmu_i2c_release_bus; sc->sc_i2c.ic_send_start = NULL; sc->sc_i2c.ic_send_stop = NULL; sc->sc_i2c.ic_initiate_xfer = NULL; sc->sc_i2c.ic_read_byte = NULL; sc->sc_i2c.ic_write_byte = NULL; sc->sc_i2c.ic_exec = pmu_i2c_exec; config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); #endif if (kthread_create(PRI_NONE, 0, NULL, pmu_thread, sc, &sc->sc_thread, "%s", "pmu") != 0) { aprint_error_dev(self, "unable to create event kthread\n"); } sc->sc_lidswitch.smpsw_name = "Lid switch"; sc->sc_lidswitch.smpsw_type = PSWITCH_TYPE_LID; if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0) aprint_error_dev(self, "unable to register lid switch with sysmon\n"); }
static int fdtbus_attach(device_t dev) { phandle_t root; phandle_t child; struct fdtbus_softc *sc; u_long start, end; int error; if ((root = OF_finddevice("/")) == -1) panic("fdtbus_attach: no root node."); sc = device_get_softc(dev); /* * IRQ rman. */ start = 0; end = ~0; sc->sc_irq.rm_start = start; sc->sc_irq.rm_end = end; sc->sc_irq.rm_type = RMAN_ARRAY; sc->sc_irq.rm_descr = "Interrupt request lines"; if ((error = rman_init(&sc->sc_irq)) != 0) { device_printf(dev, "could not init IRQ rman, error = %d\n", error); return (error); } if ((error = rman_manage_region(&sc->sc_irq, start, end)) != 0) { device_printf(dev, "could not manage IRQ region, error = %d\n", error); return (error); } /* * Mem-mapped I/O space rman. */ start = 0; end = ~0ul; sc->sc_mem.rm_start = start; sc->sc_mem.rm_end = end; sc->sc_mem.rm_type = RMAN_ARRAY; sc->sc_mem.rm_descr = "I/O memory"; if ((error = rman_init(&sc->sc_mem)) != 0) { device_printf(dev, "could not init I/O mem rman, error = %d\n", error); return (error); } if ((error = rman_manage_region(&sc->sc_mem, start, end)) != 0) { device_printf(dev, "could not manage I/O mem region, " "error = %d\n", error); return (error); } /* * Walk the FDT root node and add top-level devices as our children. */ for (child = OF_child(root); child != 0; child = OF_peer(child)) { /* Check and process 'status' property. */ if (!(fdt_is_enabled(child))) continue; newbus_device_from_fdt_node(dev, child); } return (bus_generic_attach(dev)); }
/* the backdoor to the keyboard controller! XXX */ int atkbdc_configure(void) { bus_space_tag_t tag; bus_space_handle_t h0; bus_space_handle_t h1; #if defined(__i386__) || defined(__amd64__) volatile int i; register_t flags; #endif #ifdef __sparc64__ char name[32]; phandle_t chosen, node; ihandle_t stdin; bus_addr_t port0; bus_addr_t port1; int space; #else int port0; int port1; #endif /* XXX: tag should be passed from the caller */ #if defined(__amd64__) || defined(__i386__) tag = X86_BUS_SPACE_IO; #elif defined(__sparc64__) tag = &atkbdc_bst_store[0]; #else #error "define tag!" #endif #ifdef __sparc64__ if ((chosen = OF_finddevice("/chosen")) == -1) return 0; if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) return 0; if ((node = OF_instance_to_package(stdin)) == -1) return 0; if (OF_getprop(node, "name", name, sizeof(name)) == -1) return 0; name[sizeof(name) - 1] = '\0'; if (strcmp(name, "kb_ps2") != 0) return 0; /* * The stdin handle points to an instance of a PS/2 keyboard * package but we want the 8042 controller, which is the parent * of that keyboard node. */ if ((node = OF_parent(node)) == 0) return 0; if (OF_decode_addr(node, 0, &space, &port0) != 0) return 0; h0 = sparc64_fake_bustag(space, port0, tag); bus_space_subregion(tag, h0, KBD_DATA_PORT, 1, &h0); if (OF_decode_addr(node, 1, &space, &port1) != 0) return 0; h1 = sparc64_fake_bustag(space, port1, tag); bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1); #else port0 = IO_KBD; resource_int_value("atkbdc", 0, "port", &port0); port1 = IO_KBD + KBD_STATUS_PORT; #ifdef notyet bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); #else h0 = (bus_space_handle_t)port0; h1 = (bus_space_handle_t)port1; #endif #endif #if defined(__i386__) || defined(__amd64__) /* * Check if we really have AT keyboard controller. Poll status * register until we get "all clear" indication. If no such * indication comes, it probably means that there is no AT * keyboard controller present. Give up in such case. Check relies * on the fact that reading from non-existing in/out port returns * 0xff on i386. May or may not be true on other platforms. */ flags = intr_disable(); for (i = 0; i != 65535; i++) { if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0) break; } intr_restore(flags); if (i == 65535) return ENXIO; #endif return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); }
int main(int (*openfirm)(void *)) { char bootpath[64]; struct devsw **dp; phandle_t chosenh; /* * Tell the OpenFirmware functions where they find the ofw gate. */ OF_init(openfirm); archsw.arch_getdev = ofw_getdev; archsw.arch_copyin = sparc64_copyin; archsw.arch_copyout = ofw_copyout; archsw.arch_readin = sparc64_readin; archsw.arch_autoload = sparc64_autoload; init_heap(); setheap((void *)heapva, (void *)(heapva + HEAPSZ)); /* * Probe for a console. */ cons_probe(); tlb_init(); bcache_init(32, 512); /* * Initialize devices. */ for (dp = devsw; *dp != 0; dp++) { if ((*dp)->dv_init != 0) (*dp)->dv_init(); } /* * Set up the current device. */ chosenh = OF_finddevice("/chosen"); OF_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); /* * Sun compatible bootable CD-ROMs have a disk label placed * before the cd9660 data, with the actual filesystem being * in the first partition, while the other partitions contain * pseudo disk labels with embedded boot blocks for different * architectures, which may be followed by UFS filesystems. * The firmware will set the boot path to the partition it * boots from ('f' in the sun4u case), but we want the kernel * to be loaded from the cd9660 fs ('a'), so the boot path * needs to be altered. */ if (bootpath[strlen(bootpath) - 2] == ':' && bootpath[strlen(bootpath) - 1] == 'f') { bootpath[strlen(bootpath) - 1] = 'a'; printf("Boot path set to %s\n", bootpath); } env_setenv("currdev", EV_VOLATILE, bootpath, ofw_setcurrdev, env_nounset); env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset, env_nounset); printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); printf("bootpath=\"%s\"\n", bootpath); /* Give control to the machine independent loader code. */ interact(); return 1; }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; int error = 0; #ifdef SOFTRAID char volno; #endif if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name); if (strlcpy(fname, name, sizeof fname) >= sizeof fname) return ENAMETOOLONG; #ifdef SOFTRAID if (bootdev_dip) { if (fname[0] == 's' && fname[1] == 'r' && '0' <= fname[2] && fname[2] <= '9') { volno = fname[2]; if ('a' <= fname[3] && fname[3] <= 'a' + MAXPARTITIONS) { partition = fname[3]; if (fname[4] == ':') cp = &fname[5]; else cp = &fname[4]; } else { partition = 'a'; cp = &fname[3]; } } else { volno = '0'; partition = 'a'; cp = &fname[0]; } snprintf(buf, sizeof buf, "sr%c:%c", volno, partition); if (strlcpy(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; *file = opened_name + strlen(opened_name); if (!*cp) { if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf) >= sizeof buf) return ENAMETOOLONG; } else { if (snprintf(buf, sizeof buf, "%s%s", *cp == '/' ? "" : "/", cp) >= sizeof buf) return ENAMETOOLONG; } if (strlcat(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; } else { #endif cp = filename(fname, &partition); if (cp) { if (strlcpy(buf, cp, sizeof buf) >= sizeof buf) return ENAMETOOLONG; *cp = 0; } if (!cp || !*buf) { if (strlcpy(buf, DEFAULT_KERNEL, sizeof buf) >= sizeof buf) return ENAMETOOLONG; } if (!*fname) { if (strlcpy(fname, bootdev, sizeof fname) >= sizeof fname) return ENAMETOOLONG; } if (strlcpy(opened_name, fname, partition ? (sizeof opened_name) - 2 : sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') { if (strlcat(opened_name, "/", sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; } if (strlcat(opened_name, buf, sizeof opened_name) >= sizeof opened_name) return ENAMETOOLONG; *file = opened_name + strlen(fname) + 1; #ifdef SOFTRAID } #endif DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname); #ifdef SOFTRAID if (bootdev_dip) { /* Redirect to the softraid boot volume. */ struct partition *pp; bzero(&ofdev, sizeof ofdev); ofdev.type = OFDEV_SOFTRAID; if (partition) { if (partition < 'a' || partition >= 'a' + MAXPARTITIONS) { printf("invalid partition '%c'\n", partition); return EINVAL; } part = partition - 'a'; pp = &bootdev_dip->disklabel.d_partitions[part]; if (pp->p_fstype == FS_UNUSED || pp->p_size == 0) { printf("invalid partition '%c'\n", partition); return EINVAL; } bootdev_dip->sr_vol->sbv_part = partition; } else bootdev_dip->sr_vol->sbv_part = 'a'; of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #else #error "-DSOFTRAID requires -DSPARC_BOOT_UFS" #endif return 0; } #endif if ((handle = OF_finddevice(fname)) == -1) return ENOENT; DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); if ((handle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); ofdev.handle = handle; ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; if (!strcmp(buf, "block")) { error = load_disklabel(&ofdev, &label); if (error && error != ERDLAB) goto bad; else if (error == ERDLAB) { if (partition) /* User specified a parititon, but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d " "offset %x\n", part, ofdev.partoff); } of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #endif #ifdef SPARC_BOOT_HSFS bcopy(&file_system_cd9660, &file_system[nfsys++], sizeof file_system[0]); #endif DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n"); return 0; } #ifdef NETBOOT if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; bcopy(&file_system_nfs, file_system, sizeof file_system[0]); nfsys = 1; if (error = net_open(&ofdev)) goto bad; return 0; } #endif error = EFTYPE; bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); OF_close(handle); ofdev.handle = -1; return error; }
void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; int argc = a0, i;//, res; uint32_t timer_clk; char **argv = (char **)MIPS_PHYS_TO_KSEG0(a1); char **envp = (char **)MIPS_PHYS_TO_KSEG0(a2); void *dtbp; phandle_t chosen; char buf[2048]; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); dtbp = &fdt_static_dtb; if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); mtk_soc_try_early_detect(); if ((timer_clk = mtk_soc_get_timerclk()) == 0) timer_clk = 1000000000; /* no such speed yet */ mips_timer_early_init(timer_clk); /* initialize console so that we have printf */ boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ boothowto |= (RB_VERBOSE); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); /* * Get bsdbootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bsdbootargs", buf, sizeof(buf)) != -1) _parse_bootargs(buf); printf("FDT DTB at: 0x%08x\n", (uint32_t)dtbp); printf("CPU clock: %4dMHz\n", mtk_soc_get_cpuclk()/(1000*1000)); printf("Timer clock: %4dMHz\n", timer_clk/(1000*1000)); printf("UART clock: %4dMHz\n\n", mtk_soc_get_uartclk()/(1000*1000)); printf("U-Boot args (from %d args):\n", argc - 1); if (argc == 1) printf("\tNone\n"); for (i = 1; i < argc; i++) { char *n = "argv ", *arg; if (i > 99) break; if (argv[i]) { arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(argv[i]); printf("\targv[%d] = %s\n", i, arg); sprintf(n, "argv%d", i); kern_setenv(n, arg); } } printf("Environment:\n"); for (i = 0; envp[i] && MIPS_IS_VALID_PTR(envp[i]); i++) { char *n, *arg; arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(envp[i]); if (! MIPS_IS_VALID_PTR(arg)) continue; printf("\t%s\n", arg); n = strsep(&arg, "="); if (arg == NULL) kern_setenv(n, "1"); else kern_setenv(n, arg); } mips_init(); mips_timer_init_params(timer_clk, 0); }
void powermac_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, struct mem_region *avail, int *availsz) { phandle_t memory; cell_t memoryprop[PHYS_AVAIL_SZ * 2]; ssize_t propsize, i, j; int physacells = 1; memory = OF_finddevice("/memory"); if (memory == -1) memory = OF_finddevice("/memory@0"); /* "reg" has variable #address-cells, but #size-cells is always 1 */ OF_getprop(OF_parent(memory), "#address-cells", &physacells, sizeof(physacells)); propsize = OF_getprop(memory, "reg", memoryprop, sizeof(memoryprop)); propsize /= sizeof(cell_t); for (i = 0, j = 0; i < propsize; i += physacells+1, j++) { phys[j].mr_start = memoryprop[i]; if (physacells == 2) { #ifndef __powerpc64__ /* On 32-bit PPC, ignore regions starting above 4 GB */ if (memoryprop[i] != 0) { j--; continue; } #else phys[j].mr_start <<= 32; #endif phys[j].mr_start |= memoryprop[i+1]; } phys[j].mr_size = memoryprop[i + physacells]; } *physsz = j; /* "available" always has #address-cells = 1 */ propsize = OF_getprop(memory, "available", memoryprop, sizeof(memoryprop)); if (propsize <= 0) { for (i = 0; i < *physsz; i++) { avail[i].mr_start = phys[i].mr_start; avail[i].mr_size = phys[i].mr_size; } *availsz = *physsz; } else { propsize /= sizeof(cell_t); for (i = 0, j = 0; i < propsize; i += 2, j++) { avail[j].mr_start = memoryprop[i]; avail[j].mr_size = memoryprop[i + 1]; } #ifdef __powerpc64__ /* Add in regions above 4 GB to the available list */ for (i = 0; i < *physsz; i++) { if (phys[i].mr_start > BUS_SPACE_MAXADDR_32BIT) { avail[j].mr_start = phys[i].mr_start; avail[j].mr_size = phys[i].mr_size; j++; } } #endif *availsz = j; } }
static void get_bootpath_from_prom(void) { struct btinfo_bootdev *bdev = NULL; char sbuf[OFPATHLEN], *cp; int chosen; /* * Grab boot path from PROM */ if ((chosen = OF_finddevice("/chosen")) == -1) return; bdev = lookup_bootinfo(BTINFO_BOOTDEV); if (bdev != NULL) { strcpy(ofbootpath, bdev->name); } else { if (OF_getprop(chosen, "bootpath", sbuf, sizeof(sbuf)) < 0) return; strcpy(ofbootpath, sbuf); } DPRINTF(ACDB_BOOTDEV, ("bootpath: %s\n", ofbootpath)); ofbootpackage = prom_finddevice(ofbootpath); /* * Strip partition or boot protocol */ cp = strrchr(ofbootpath, ':'); if (cp) { *cp = '\0'; ofbootpartition = cp+1; } cp = strrchr(ofbootpath, '@'); if (cp) { for (; cp != ofbootpath; cp--) { if (*cp == '/') { ofboottarget = cp+1; break; } } } DPRINTF(ACDB_BOOTDEV, ("bootpath phandle: 0x%x\n", ofbootpackage)); DPRINTF(ACDB_BOOTDEV, ("boot target: %s\n", ofboottarget ? ofboottarget : "<none>")); DPRINTF(ACDB_BOOTDEV, ("boot partition: %s\n", ofbootpartition ? ofbootpartition : "<none>")); /* Setup pointer to boot flags */ if (OF_getprop(chosen, "bootargs", sbuf, sizeof(sbuf)) == -1) return; strcpy(ofbootargs, sbuf); cp = ofbootargs; /* Find start of boot flags */ while (*cp) { while(*cp == ' ' || *cp == '\t') cp++; if (*cp == '-' || *cp == '\0') break; while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++; if (*cp != '\0') *cp++ = '\0'; } if (cp != ofbootargs) ofbootfile = ofbootargs; ofbootflags = cp; if (*cp != '-') return; for (;*++cp;) { int fl; fl = 0; BOOT_FLAG(*cp, fl); if (!fl) { printf("unknown option `%c'\n", *cp); continue; } boothowto |= fl; /* specialties */ if (*cp == 'd') { #if defined(KGDB) kgdb_break_at_attach = 1; #elif defined(DDB) Debugger(); #else printf("kernel has no debugger\n"); #endif } else if (*cp == 't') { /* turn on traptrace w/o breaking into kdb */ extern int trap_trace_dis; trap_trace_dis = 0; } } }
int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { char buf[64]; struct uart_class *class; phandle_t input, opts, chosen; int error; opts = OF_finddevice("/options"); chosen = OF_finddevice("/chosen"); switch (devtype) { case UART_DEV_CONSOLE: error = ENXIO; if (chosen != -1 && error != 0) error = ofw_get_uart_console(chosen, &input, "stdout-path", NULL); if (chosen != -1 && error != 0) error = ofw_get_uart_console(chosen, &input, "linux,stdout-path", NULL); if (chosen != -1 && error != 0) error = ofw_get_console_phandle_path(chosen, &input, "stdout"); if (chosen != -1 && error != 0) error = ofw_get_uart_console(chosen, &input, "stdin-path", NULL); if (chosen != -1 && error != 0) error = ofw_get_console_phandle_path(chosen, &input, "stdin"); if (opts != -1 && error != 0) error = ofw_get_uart_console(opts, &input, "input-device", "output-device"); if (opts != -1 && error != 0) error = ofw_get_uart_console(opts, &input, "input-device-1", "output-device-1"); if (error != 0) { input = OF_finddevice("serial0"); /* Last ditch */ if (input == -1) error = (ENXIO); } if (error != 0) return (error); break; case UART_DEV_DBGPORT: if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf))) return (ENXIO); input = OF_finddevice(buf); if (input == -1) return (ENXIO); break; default: return (EINVAL); } if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) return (ENXIO); if (strcmp(buf, "serial") != 0) return (ENXIO); if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1) return (ENXIO); if (strncmp(buf, "chrp,es", 7) == 0) { class = &uart_z8530_class; di->bas.regshft = 4; di->bas.chan = 1; } else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
/* * Called back during autoconfiguration for each device found */ void device_register(device_t dev, void *aux) { device_t busdev = device_parent(dev); int ofnode = 0; /* * We don't know the type of 'aux' - it depends on the * bus this device attaches to. We are only interested in * certain bus types, this only is used to find the boot * device. */ if (busdev == NULL) { /* * Ignore mainbus0 itself, it certainly is not a boot * device. */ } else if (device_is_a(busdev, "mainbus")) { struct mainbus_attach_args *ma = aux; ofnode = ma->ma_node; } else if (device_is_a(busdev, "pci")) { struct pci_attach_args *pa = aux; ofnode = PCITAG_NODE(pa->pa_tag); } else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma") || device_is_a(busdev, "ledma")) { struct sbus_attach_args *sa = aux; ofnode = sa->sa_node; } else if (device_is_a(busdev, "ebus")) { struct ebus_attach_args *ea = aux; ofnode = ea->ea_node; } else if (device_is_a(busdev, "iic")) { struct i2c_attach_args *ia = aux; if (ia->ia_name == NULL) /* indirect config */ return; ofnode = (int)ia->ia_cookie; } else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; int off = 0; /* * There are two "cd" attachments: * atapibus -> atabus -> controller * scsibus -> controller * We want the node of the controller. */ if (device_is_a(busdev, "atapibus")) { busdev = device_parent(busdev); /* * if the atapibus is connected to the secondary * channel of the atabus, we need an offset of 2 * to match OF's idea of the target number. * (i.e. on U5/U10 "cdrom" and "disk2" have the * same target encoding, though different names) */ if (periph->periph_channel->chan_channel == 1) off = 2; } ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, periph->periph_target + off, 0, periph->periph_lun); return; } else if (device_is_a(dev, "wd")) { struct ata_device *adev = aux; ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, adev->adev_channel*2+ adev->adev_drv_data->drive, 0, 0); return; } if (busdev == NULL) return; if (ofnode != 0) { uint8_t eaddr[ETHER_ADDR_LEN]; char tmpstr[32]; char tmpstr2[32]; int node; uint32_t id = 0; uint64_t nwwn = 0, pwwn = 0; prop_dictionary_t dict; prop_data_t blob; prop_number_t pwwnd = NULL, nwwnd = NULL; prop_number_t idd = NULL; device_setofnode(dev, ofnode); dev_path_exact_match(dev, ofnode); if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0) tmpstr[0] = 0; if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0) tmpstr2[0] = 0; /* * If this is a network interface, note the * mac address. */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr, "ethernet") == 0 || strcmp(tmpstr2, "network") == 0 || strcmp(tmpstr2, "ethernet") == 0 || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN) { dict = device_properties(dev); /* * Is it a network interface with FCode? */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr2, "network") == 0) { prop_dictionary_set_bool(dict, "without-seeprom", true); prom_getether(ofnode, eaddr); } else { if (!prom_get_node_ether(ofnode, eaddr)) goto noether; } blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN); prop_dictionary_set(dict, "mac-address", blob); prop_object_release(blob); of_to_dataprop(dict, ofnode, "shared-pins", "shared-pins"); } noether: /* is this a FC node? */ if (strcmp(tmpstr, "scsi-fcp") == 0) { dict = device_properties(dev); if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn)) == sizeof(pwwn)) { pwwnd = prop_number_create_unsigned_integer(pwwn); prop_dictionary_set(dict, "port-wwn", pwwnd); prop_object_release(pwwnd); } if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn)) == sizeof(nwwn)) { nwwnd = prop_number_create_unsigned_integer(nwwn); prop_dictionary_set(dict, "node-wwn", nwwnd); prop_object_release(nwwnd); } } /* is this an spi device? look for scsi-initiator-id */ if (strcmp(tmpstr2, "scsi") == 0 || strcmp(tmpstr2, "scsi-2") == 0) { dict = device_properties(dev); for (node = ofnode; node != 0; node = OF_parent(node)) { if (OF_getprop(node, "scsi-initiator-id", &id, sizeof(id)) <= 0) continue; idd = prop_number_create_unsigned_integer(id); prop_dictionary_set(dict, "scsi-initiator-id", idd); prop_object_release(idd); break; } } } /* * Check for I2C busses and add data for their direct configuration. */ if (device_is_a(dev, "iic")) { int busnode = device_ofnode(busdev); if (busnode) { prop_dictionary_t props = device_properties(busdev); prop_object_t cfg = prop_dictionary_get(props, "i2c-child-devices"); if (!cfg) { int node; const char *name; /* * pmu's i2c devices are under the "i2c" node, * so find it out. */ name = prom_getpropstring(busnode, "name"); if (strcmp(name, "pmu") == 0) { for (node = OF_child(busnode); node != 0; node = OF_peer(node)) { name = prom_getpropstring(node, "name"); if (strcmp(name, "i2c") == 0) { busnode = node; break; } } } of_enter_i2c_devs(props, busnode, sizeof(cell_t)); } } /* * Add SPARCle spdmem devices (0x50 and 0x51) that the * firmware does not know about. */ if (!strcmp(machine_model, "TAD,SPARCLE")) { prop_dictionary_t props = device_properties(busdev); prop_array_t cfg = prop_array_create(); int i; DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle ")); for (i = 0x50; i <= 0x51; i++) { prop_dictionary_t spd = prop_dictionary_create(); prop_dictionary_set_cstring(spd, "name", "dimm-spd"); prop_dictionary_set_uint32(spd, "addr", i); prop_dictionary_set_uint64(spd, "cookie", 0); prop_array_add(cfg, spd); prop_object_release(spd); } prop_dictionary_set(props, "i2c-child-devices", cfg); prop_object_release(cfg); } } /* set properties for PCI framebuffers */ if (device_is_a(busdev, "pci")) { /* see if this is going to be console */ struct pci_attach_args *pa = aux; prop_dictionary_t dict; int sub; int console = 0; dict = device_properties(dev); /* we only care about display devices from here on */ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) return; console = (ofnode == console_node); if (!console) { /* * see if any child matches since OF attaches * nodes for each head and /chosen/stdout * points to the head rather than the device * itself in this case */ sub = OF_child(ofnode); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } copyprops(busdev, ofnode, dict, console); if (console) { uint64_t cmap_cb; prop_dictionary_set_uint32(dict, "instance_handle", console_instance); gfb_cb.gcc_cookie = (void *)(intptr_t)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); } #ifdef notyet else { int width; /* * the idea is to 'open' display devices with no useful * properties, in the hope that the firmware will * properly initialize them and we can run things like * genfb on them */ if (OF_getprop(node, "width", &width, sizeof(width)) != 4) { instance = OF_open(name); #endif } } /* * Called back after autoconfiguration of a device is done */ void device_register_post_config(device_t dev, void *aux) { if (booted_device == NULL && device_is_a(dev, "sd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; uint64_t wwn = 0; int ofnode; /* * If this is a FC-AL drive it will have * aquired its WWN device property by now, * so we can properly match it. */ if (prop_dictionary_get_uint64(device_properties(dev), "port-wwn", &wwn)) { /* * Different to what we do in device_register, * we do not pass the "controller" ofnode, * because FC-AL devices attach below a "fp" node, * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk * and we need the parent of "disk" here. */ ofnode = device_ofnode( device_parent(device_parent(dev))); for (ofnode = OF_child(ofnode); ofnode != 0 && booted_device == NULL; ofnode = OF_peer(ofnode)) { dev_path_drive_match(dev, ofnode, periph->periph_target, wwn, periph->periph_lun); } } } } static void copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console) { device_t cntrlr; prop_dictionary_t psycho; paddr_t fbpa, mem_base = 0; uint32_t temp, fboffset; uint32_t fbaddr = 0; int options; char output_device[256]; char *pos; cntrlr = device_parent(busdev); if (cntrlr != NULL) { psycho = device_properties(cntrlr); prop_dictionary_get_uint64(psycho, "mem_base", &mem_base); } if (is_console) prop_dictionary_set_bool(dict, "is_console", 1); of_to_uint32_prop(dict, node, "width", "width"); of_to_uint32_prop(dict, node, "height", "height"); of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth") && /* Some cards have an extra space in the property name */ !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); } OF_getprop(node, "address", &fbaddr, sizeof(fbaddr)); if (fbaddr != 0) { pmap_extract(pmap_kernel(), fbaddr, &fbpa); #ifdef DEBUG printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base, (unsigned long)fbpa); #endif if (mem_base == 0) { /* XXX this is guesswork */ fboffset = (uint32_t)(fbpa & 0xffffffff); } fboffset = (uint32_t)(fbpa - mem_base); prop_dictionary_set_uint32(dict, "address", fboffset); } if (!of_to_dataprop(dict, node, "EDID", "EDID")) of_to_dataprop(dict, node, "edid", "EDID"); temp = 0; if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); /* * finally, let's see if there's a video mode specified in * output-device and pass it on so drivers like radeonfb * can do their thing */ if (!is_console) return; options = OF_finddevice("/options"); if ((options == 0) || (options == -1)) return; if (OF_getprop(options, "output-device", output_device, 256) == 0) return; /* find the mode string if there is one */ pos = strstr(output_device, ":r"); if (pos == NULL) return; prop_dictionary_set_cstring(dict, "videomode", pos + 2); } static void of_set_palette(void *cookie, int index, int r, int g, int b) { int ih = (int)((intptr_t)cookie); OF_call_method_1("color!", ih, 4, r, g, b, index); }
int devopen(struct open_file *of, const char *name, char **file) { char *cp; char partition; char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; int handle, part; size_t read; char *errmsg = NULL; int error = 0; if (ofdev.handle != -1) panic("devopen"); if (of->f_flags != F_READ) return EPERM; DNPRINTF(BOOT_D_OFDEV, "devopen: you want %s\n", name); strlcpy(fname, name, sizeof fname); cp = filename(fname, &partition); if (cp) { strlcpy(buf, cp, sizeof buf); *cp = 0; } if (!cp || !*buf) strlcpy(buf, DEFAULT_KERNEL, sizeof buf); if (!*fname) strlcpy(fname, bootdev, sizeof fname); strlcpy(opened_name, fname, sizeof opened_name); if (partition) { cp = opened_name + strlen(opened_name); *cp++ = ':'; *cp++ = partition; *cp = 0; } if (*buf != '/') strlcat(opened_name, "/", sizeof opened_name); strlcat(opened_name, buf, sizeof opened_name); *file = opened_name + strlen(fname) + 1; DNPRINTF(BOOT_D_OFDEV, "devopen: trying %s\n", fname); if ((handle = OF_finddevice(fname)) == -1) return ENOENT; DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is called %s\n", fname, buf); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; DNPRINTF(BOOT_D_OFDEV, "devopen: %s is a %s device\n", fname, buf); DNPRINTF(BOOT_D_OFDEV, "devopen: opening %s\n", fname); if ((handle = OF_open(fname)) == -1) { DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); return ENXIO; } DNPRINTF(BOOT_D_OFDEV, "devopen: %s is now open\n", fname); bzero(&ofdev, sizeof ofdev); ofdev.handle = handle; if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; /* First try to find a disklabel without MBR partitions */ DNPRINTF(BOOT_D_OFDEV, "devopen: trying to read disklabel\n"); if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read) != 0 || read != DEV_BSIZE || (errmsg = getdisklabel(buf, &label))) { #ifdef BOOT_DEBUG if (errmsg) DNPRINTF(BOOT_D_OFDEV, "devopen: getdisklabel says %s\n", errmsg); #endif /* Else try MBR partitions */ errmsg = search_label(&ofdev, LABELSECTOR, buf, &label, 0); if (errmsg) { printf("devopen: search_label says %s\n", errmsg); error = ERDLAB; } if (error && error != ERDLAB) goto bad; } if (error == ERDLAB) { if (partition) /* User specified a parititon, but there is none */ goto bad; /* No, label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; DNPRINTF(BOOT_D_OFDEV, "devopen: setting partition %d " "offset %x\n", part, ofdev.partoff); } of->f_dev = devsw; of->f_devdata = &ofdev; #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); #endif #ifdef SPARC_BOOT_HSFS bcopy(&file_system_cd9660, &file_system[nfsys++], sizeof file_system[0]); #endif DNPRINTF(BOOT_D_OFDEV, "devopen: return 0\n"); return 0; } #ifdef NETBOOT if (!strcmp(buf, "network")) { ofdev.type = OFDEV_NET; of->f_dev = devsw; of->f_devdata = &ofdev; bcopy(&file_system_nfs, file_system, sizeof file_system[0]); nfsys = 1; if (error = net_open(&ofdev)) goto bad; return 0; } #endif error = EFTYPE; bad: DNPRINTF(BOOT_D_OFDEV, "devopen: error %d, cannot open device\n", error); OF_close(handle); ofdev.handle = -1; return error; }
asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer) { int phandle,i,mem_len,buffer[32]; char temp[15]; temp[0]='/'; temp[1]='m'; temp[2]='e'; temp[3]='m'; temp[4]='o'; temp[5]='r'; temp[6]='y'; temp[7]='\0'; phandle=OF_finddevice(o,temp); temp[0]='r'; temp[1]='e'; temp[2]='g'; temp[3]='\0'; mem_len = OF_getproplen(o,phandle, temp); OF_getprop(o,phandle, temp, buffer, mem_len); *nomr=mem_len >> 3; for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]); temp[0]='/'; temp[1]='c'; temp[2]='h'; temp[3]='o'; temp[4]='s'; temp[5]='e'; temp[6]='n'; temp[7]='\0'; phandle=OF_finddevice(o,temp); temp[0]='b'; temp[1]='o'; temp[2]='o'; temp[3]='t'; temp[4]='a'; temp[5]='r'; temp[6]='g'; temp[7]='s'; temp[8]='\0'; mem_len = OF_getproplen(o,phandle, temp); OF_getprop(o,phandle, temp, buffer, mem_len); if (mem_len > 128) mem_len=128; for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i]; pointer[i+33]=0; temp[0]='/'; temp[1]='\0'; phandle=OF_finddevice(o,temp); temp[0]='b'; temp[1]='a'; temp[2]='n'; temp[3]='n'; temp[4]='e'; temp[5]='r'; temp[6]='-'; temp[7]='n'; temp[8]='a'; temp[9]='m'; temp[10]='e'; temp[11]='\0'; mem_len = OF_getproplen(o,phandle, temp); OF_getprop(o,phandle, temp, buffer, mem_len); (unsigned char) pointer[32] = ((unsigned char *) buffer)[mem_len-2]; }
/* * 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 kauaiataattach(struct device *parent, struct device *self, void *aux) { int node; struct confargs ca; int namelen; u_int32_t reg[20]; char name[32]; int32_t intr[8]; struct kauaiata_softc *sc = (struct kauaiata_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; /* XXX assumes that this is /pci@f400000/ata-6 */ /* vendor 0x106b product 0x003b (class undefined unknown subclass 0x00, rev 0x00) at pci2 dev 13 function 0 not configured */ node = OF_finddevice("/pci@f4000000/ata-6"); /* * XXX - need to compare node and PCI id to verify this is the * correct device. */ ca.ca_nreg = OF_getprop(node, "reg", reg, sizeof(reg)); intr[0] = PCI_INTERRUPT_LINE(pci_conf_read(pc, pa->pa_tag, PCI_INTERRUPT_REG)); ca.ca_nintr = 4; /* claim to have 4 bytes of interrupt info */ /* This needs to come from INTERRUPT REG above, but is not filled out */ intr[0] = 0x27; namelen = OF_getprop(node, "name", name, sizeof(name)); if ((namelen < 0) || (namelen >= sizeof(name))) { printf(" bad name prop len %x\n", namelen); return; } name[namelen] = 0; /* name property may not be null terminated */ /* config read */ sc->sc_membus_space.bus_base = pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START); #if 0 pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, 0xffffffff); size = ~(pci_conf_read(pc, pa->pa_tag, PCI_MAPREG_START)); pci_conf_write(pc, pa->pa_tag, PCI_MAPREG_START, sc->sc_membus_space.bus_base); #endif ca.ca_baseaddr = sc->sc_membus_space.bus_base; sc->sc_membus_space.bus_reverse = 1; ca.ca_name = name; ca.ca_iot = &sc->sc_membus_space; ca.ca_dmat = pa->pa_dmat; ca.ca_reg = reg; reg[0] = 0x2000; /* offset to wdc registers */ reg[1] = reg[9] - 0x2000; /* map size of wdc registers */ reg[2] = 0x1000; /* offset to dbdma registers */ reg[3] = 0x1000; /* map size of dbdma registers */ ca.ca_intr = intr; printf("\n"); config_found(self, &ca, kauaiata_print); }
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); }