Пример #1
0
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;
}
Пример #2
0
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");
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
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));
}
Пример #7
0
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;
}
Пример #8
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 = &sc;
	return;
	
fail:
	cp->cn_pri = CN_DEAD;
	return;
}
Пример #9
0
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));
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
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);
    }
}
Пример #14
0
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);
}
Пример #15
0
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);
}
Пример #16
0
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");
}
Пример #17
0
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));
}
Пример #18
0
/* 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);
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
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);
}
Пример #22
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;
	}
}
Пример #23
0
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;
		}
	}
}
Пример #24
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) {
Пример #25
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);
}
Пример #26
0
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;
}
Пример #27
0
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];
}
Пример #28
0
/*
 * 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);
	}
}
Пример #29
0
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);
}
Пример #30
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);
}