示例#1
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);
}
示例#2
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);
}