Ejemplo n.º 1
0
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
	char buf[32], compat[32], dev[64];
	struct uart_class *class;
	phandle_t input, options;
	bus_addr_t addr;
	int baud, bits, error, range, space, stop;
	char flag, par;

	if ((options = OF_finddevice("/options")) == -1)
		return (ENXIO);
	switch (devtype) {
	case UART_DEV_CONSOLE:
		input = uart_cpu_getdev_console(options, dev, sizeof(dev));
		break;
	case UART_DEV_DBGPORT:
		input = uart_cpu_getdev_dbgport(dev, sizeof(dev));
		break;
	case UART_DEV_KEYBOARD:
		input = uart_cpu_getdev_keyboard(dev, sizeof(dev));
		break;
	default:
		input = -1;
		break;
	}
	if (input == -1)
		return (ENXIO);
	error = OF_decode_addr(input, 0, &space, &addr);
	if (error)
		return (error);

	/* Get the device class. */
	if (OF_getprop(input, "name", buf, sizeof(buf)) == -1)
		return (ENXIO);
	if (OF_getprop(input, "compatible", compat, sizeof(compat)) == -1)
		compat[0] = '\0';
	di->bas.regshft = 0;
	di->bas.rclk = 0;
	class = NULL;
	if (!strcmp(buf, "se") || !strcmp(buf, "FJSV,se") ||
	    !strcmp(compat, "sab82532")) {
		class = &uart_sab82532_class;
		/* SAB82532 are only known to be used for TTYs. */
		if ((di->bas.chan = uart_cpu_channel(dev)) == 0)
			return (ENXIO);
		addr += uart_getrange(class) * (di->bas.chan - 1);
	} else if (!strcmp(buf, "zs")) {
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
static int
tsec_fdt_attach(device_t dev)
{
	struct tsec_softc *sc;
	phandle_t phy;
	int error = 0;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->node = ofw_bus_get_node(dev);

	/* Get phy address from fdt */
	if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) {
		device_printf(dev, "PHY not found in device tree");
		return (ENXIO);
	}

	phy = OF_node_from_xref(phy);
	OF_decode_addr(OF_parent(phy), 0, &sc->phy_bst, &sc->phy_bsh);
	OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr));

	/* Init timer */
	callout_init(&sc->tsec_callout, 1);

	/* Init locks */
	mtx_init(&sc->transmit_lock, device_get_nameunit(dev), "TSEC TX lock",
	    MTX_DEF);
	mtx_init(&sc->receive_lock, device_get_nameunit(dev), "TSEC RX lock",
	    MTX_DEF);
	mtx_init(&sc->ic_lock, device_get_nameunit(dev), "TSEC IC lock",
	    MTX_DEF);

	/* Allocate IO memory for TSEC registers */
	sc->sc_rrid = 0;
	sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
	    RF_ACTIVE);
	if (sc->sc_rres == NULL) {
		device_printf(dev, "could not allocate IO memory range!\n");
		goto fail1;
	}
	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);

	/* TSEC attach */
	if (tsec_attach(sc) != 0) {
		device_printf(dev, "could not be configured\n");
		goto fail2;
	}

	/* Set up interrupts (TX/RX/ERR) */
	sc->sc_transmit_irid = TSEC_RID_TXIRQ;
	error = tsec_setup_intr(sc, &sc->sc_transmit_ires,
	    &sc->sc_transmit_ihand, &sc->sc_transmit_irid,
	    tsec_transmit_intr, "TX");
	if (error)
		goto fail2;

	sc->sc_receive_irid = TSEC_RID_RXIRQ;
	error = tsec_setup_intr(sc, &sc->sc_receive_ires,
	    &sc->sc_receive_ihand, &sc->sc_receive_irid,
	    tsec_receive_intr, "RX");
	if (error)
		goto fail3;

	sc->sc_error_irid = TSEC_RID_ERRIRQ;
	error = tsec_setup_intr(sc, &sc->sc_error_ires,
	    &sc->sc_error_ihand, &sc->sc_error_irid,
	    tsec_error_intr, "ERR");
	if (error)
		goto fail4;

	return (0);

fail4:
	tsec_release_intr(sc, sc->sc_receive_ires, sc->sc_receive_ihand,
	    sc->sc_receive_irid, "RX");
fail3:
	tsec_release_intr(sc, sc->sc_transmit_ires, sc->sc_transmit_ihand,
	    sc->sc_transmit_irid, "TX");
fail2:
	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
fail1:
	mtx_destroy(&sc->receive_lock);
	mtx_destroy(&sc->transmit_lock);
	return (ENXIO);
}
Ejemplo n.º 4
0
static int
ofwfb_configure(int flags)
{
	struct ofwfb_softc *sc;
        phandle_t chosen;
        ihandle_t stdout;
	phandle_t node;
	uint32_t fb_phys;
	int depth;
	int disable;
	int len;
	int i;
	char type[16];
	static int done = 0;

	disable = 0;
	TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
	if (disable != 0)
		return (0);

	if (done != 0)
		return (0);
	done = 1;

	sc = &ofwfb_softc;

	chosen = OF_finddevice("/chosen");
	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
        node = OF_instance_to_package(stdout);
	if (node == -1) {
		/*
		 * The "/chosen/stdout" does not exist try
		 * using "screen" directly.
		 */
		node = OF_finddevice("screen");
	}
	OF_getprop(node, "device_type", type, sizeof(type));
	if (strcmp(type, "display") != 0)
		return (0);

	/* Only support 8 and 32-bit framebuffers */
	OF_getprop(node, "depth", &depth, sizeof(depth));
	if (depth == 8) {
		sc->sc_blank = ofwfb_blank_display8;
		sc->sc_putc = ofwfb_putc8;
		sc->sc_putm = ofwfb_putm8;
		sc->sc_set_border = ofwfb_set_border8;
	} else if (depth == 32) {
		sc->sc_blank = ofwfb_blank_display32;
		sc->sc_putc = ofwfb_putc32;
		sc->sc_putm = ofwfb_putm32;
		sc->sc_set_border = ofwfb_set_border32;
	} else
		return (0);

	if (OF_getproplen(node, "height") != sizeof(sc->sc_height) ||
	    OF_getproplen(node, "width") != sizeof(sc->sc_width) ||
	    OF_getproplen(node, "linebytes") != sizeof(sc->sc_stride))
		return (0);

	sc->sc_depth = depth;
	sc->sc_node = node;
	sc->sc_console = 1;
	OF_getprop(node, "height", &sc->sc_height, sizeof(sc->sc_height));
	OF_getprop(node, "width", &sc->sc_width, sizeof(sc->sc_width));
	OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));

	/*
	 * Get the PCI addresses of the adapter. The node may be the
	 * child of the PCI device: in that case, try the parent for
	 * the assigned-addresses property.
	 */
	len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
	          sizeof(sc->sc_pciaddrs));
	if (len == -1) {
		len = OF_getprop(OF_parent(node), "assigned-addresses",
		    sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs));
	}
	if (len == -1)
		len = 0;
	sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);

	/*
	 * Grab the physical address of the framebuffer, and then map it
	 * into our memory space. If the MMU is not yet up, it will be
	 * remapped for us when relocation turns on.
	 *
	 * XXX We assume #address-cells is 1 at this point.
	 */
	if (OF_getproplen(node, "address") == sizeof(fb_phys)) {
		OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
		sc->sc_tag = &bs_be_tag;
		bus_space_map(sc->sc_tag, fb_phys, sc->sc_height *
		    sc->sc_stride, BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr);
	} else {
		/*
		 * Some IBM systems don't have an address property. Try to
		 * guess the framebuffer region from the assigned addresses.
		 * This is ugly, but there doesn't seem to be an alternative.
		 * Linux does the same thing.
		 */

		fb_phys = sc->sc_num_pciaddrs;
		for (i = 0; i < sc->sc_num_pciaddrs; i++) {
			/* If it is too small, not the framebuffer */
			if (sc->sc_pciaddrs[i].size_lo <
			    sc->sc_stride*sc->sc_height)
				continue;
			/* If it is not memory, it isn't either */
			if (!(sc->sc_pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_SPACE_MEM32))
				continue;

			/* This could be the framebuffer */
			fb_phys = i;

			/* If it is prefetchable, it certainly is */
			if (sc->sc_pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_PREFETCHABLE)
				break;
		}
		if (fb_phys == sc->sc_num_pciaddrs)
			return (0);

		OF_decode_addr(node, fb_phys, &sc->sc_tag, &sc->sc_addr);
	}

	ofwfb_init(0, &sc->sc_va, 0);

	return (0);
}
Ejemplo n.º 5
0
static int
vt_efb_init(struct vt_device *vd)
{
	struct ofw_pci_register pciaddrs[8];
	struct fb_info *info;
	int i, len, n_pciaddrs;
	phandle_t node;

	if (vd->vd_softc == NULL)
		vd->vd_softc = (void *)&local_info;

	info = vd->vd_softc;

	node = vt_efb_get_fbnode();
	if (node == -1)
		return (CN_DEAD);

#define	GET(name, var)							\
	if (OF_getproplen(node, (name)) != sizeof(info->fb_##var))	\
		return (CN_DEAD);					\
	OF_getencprop(node, (name), &info->fb_##var, sizeof(info->fb_##var)); \
	if (info->fb_##var == 0)					\
		return (CN_DEAD);

	GET("height", height)
	GET("width", width)
	GET("depth", depth)
	GET("linebytes", stride)
#undef GET

	info->fb_size = info->fb_height * info->fb_stride;

	/*
	 * Get the PCI addresses of the adapter, if present. The node may be the
	 * child of the PCI device: in that case, try the parent for
	 * the assigned-addresses property.
	 */
	len = OF_getprop(node, "assigned-addresses", pciaddrs,
	    sizeof(pciaddrs));
	if (len == -1) {
		len = OF_getprop(OF_parent(node), "assigned-addresses",
		    pciaddrs, sizeof(pciaddrs));
	}
	if (len == -1)
		len = 0;
	n_pciaddrs = len / sizeof(struct ofw_pci_register);

	/*
	 * Grab the physical address of the framebuffer, and then map it
	 * into our memory space. If the MMU is not yet up, it will be
	 * remapped for us when relocation turns on.
	 */
	if (OF_getproplen(node, "address") == sizeof(info->fb_pbase)) {
	 	/* XXX We assume #address-cells is 1 at this point. */
		OF_getencprop(node, "address", &info->fb_pbase,
		    sizeof(info->fb_pbase));

	#if defined(__powerpc__)
		sc->sc_memt = &bs_be_tag;
		bus_space_map(sc->sc_memt, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE, &info->fb_vbase);
	#elif defined(__sparc64__)
		OF_decode_addr(node, 0, &space, &phys);
		sc->sc_memt = &vt_efb_memt[0];
		info->addr = sparc64_fake_bustag(space, fb_phys, sc->sc_memt);
	#else
		bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE,
		    (bus_space_handle_t *)&info->fb_vbase);
	#endif
	} else {
		/*
		 * Some IBM systems don't have an address property. Try to
		 * guess the framebuffer region from the assigned addresses.
		 * This is ugly, but there doesn't seem to be an alternative.
		 * Linux does the same thing.
		 */

		info->fb_pbase = n_pciaddrs;
		for (i = 0; i < n_pciaddrs; i++) {
			/* If it is too small, not the framebuffer */
			if (pciaddrs[i].size_lo < info->fb_size)
				continue;
			/* If it is not memory, it isn't either */
			if (!(pciaddrs[i].phys_hi &
			    OFW_PCI_PHYS_HI_SPACE_MEM32))
				continue;

			/* This could be the framebuffer */
			info->fb_pbase = i;

			/* If it is prefetchable, it certainly is */
			if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
				break;
		}

		if (info->fb_pbase == n_pciaddrs) /* No candidates found */
			return (CN_DEAD);

	#if defined(__powerpc__)
		OF_decode_addr(node, info->fb_pbase, &sc->sc_memt,
		    &info->fb_vbase);
	#elif defined(__sparc64__)
		OF_decode_addr(node, info->fb_pbase, &space, &info->fb_pbase);
		sc->sc_memt = &vt_efb_memt[0];
		info->fb_vbase = sparc64_fake_bustag(space, info->fb_pbase,
		    sc->sc_memt);
	#else
		bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
		    BUS_SPACE_MAP_PREFETCHABLE,
		    (bus_space_handle_t *)&info->fb_vbase);
	#endif
	}

	/* blank full size */
	len = info->fb_size / 4;
	for (i = 0; i < len; i++) {
		((uint32_t *)info->fb_vbase)[i] = 0;
	}

	/* Get pixel storage size. */
	info->fb_bpp = info->fb_stride / info->fb_width * 8;

#ifdef	FDT
	vt_efb_initialize(info, node);
#else
	vt_efb_initialize(info);
#endif
	vt_fb_init(vd);

	return (CN_INTERNAL);
}