Beispiel #1
0
static int
xboxfb_init(struct vt_device *vd)
{
	struct fb_info *info;
	int i;

	if (!arch_i386_is_xbox)
		return (CN_DEAD);

	info = &xboxfb_info;
	/*
	 * We must make a mapping from video framebuffer memory
	 * to real. This is very crude:  we map the entire
	 * videomemory to PAGE_SIZE! Since our kernel lives at
	 * it's relocated address range (0xc0xxxxxx), it won't
	 * care.
	 *
	 * We use address PAGE_SIZE and up so we can still trap
	 * NULL pointers.  Once the real init is called, the
	 * mapping will be done via the OS and stored in a more
	 * sensible location ... but since we're not fully
	 * initialized, this is our only way to go :-(
	 */
	for (i = 0; i < (XBOX_FB_SIZE / PAGE_SIZE); i++) {
		pmap_kenter(((i + 1) * PAGE_SIZE),
		    XBOX_FB_START + (i * PAGE_SIZE));
	}
	pmap_kenter((i + 1) * PAGE_SIZE,
	    XBOX_FB_START_PTR - XBOX_FB_START_PTR % PAGE_SIZE);

	/* Ensure the framebuffer is where we want it to be. */
	*(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) =
	    XBOX_FB_START;

	/* Initialize fb_info. */
	info = vd->vd_softc;

	info->fb_width = VT_XBOX_WIDTH;
	info->fb_height = VT_XBOX_HEIGHT;

	info->fb_size = XBOX_FB_SIZE;
	info->fb_stride = VT_XBOX_WIDTH * 4; /* 32bits per pixel. */

	info->fb_vbase = PAGE_SIZE;
	info->fb_pbase = XBOX_FB_START_PTR;

	/* Get pixel storage size. */
	info->fb_bpp = 32;
	/* Get color depth. */
	info->fb_depth = 24;

	vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255,
	    8, 255, 16);
	fb_probe(info);
	vt_fb_init(vd);

	return (CN_INTERNAL);
}
Beispiel #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);
}
Beispiel #3
0
static int
vt_efifb_init(struct vt_device *vd)
{
	int		depth, d;
	struct fb_info	*info;
	struct efi_fb	*efifb;
	caddr_t		kmdp;

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

	kmdp = preload_search_by_type("elf kernel");
	if (kmdp == NULL)
		kmdp = preload_search_by_type("elf64 kernel");
	efifb = (struct efi_fb *)preload_search_info(kmdp,
	    MODINFO_METADATA | MODINFOMD_EFI_FB);
	if (efifb == NULL)
		return (CN_DEAD);

	info->fb_height = efifb->fb_height;
	info->fb_width = efifb->fb_width;

	depth = fls(efifb->fb_mask_red);
	d = fls(efifb->fb_mask_green);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_blue);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_reserved);
	depth = d > depth ? d : depth;
	info->fb_depth = depth;

	info->fb_stride = efifb->fb_stride * (depth / 8);

	vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB,
	    efifb->fb_mask_red, ffs(efifb->fb_mask_red) - 1,
	    efifb->fb_mask_green, ffs(efifb->fb_mask_green) - 1,
	    efifb->fb_mask_blue, ffs(efifb->fb_mask_blue) - 1);

	info->fb_size = info->fb_height * info->fb_stride;
	info->fb_pbase = efifb->fb_addr;
	/*
	 * Use the direct map as a crutch until pmap is available. Once pmap
	 * is online, the framebuffer will be remapped by vt_efifb_remap()
	 * using pmap_mapdev_attr().
	 */
	info->fb_vbase = PHYS_TO_DMAP(efifb->fb_addr);

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

	/*
	 * Early FB driver work with static window buffer, so reduce to minimal
	 * size, buffer or screen.
	 */
	info->fb_width = MIN(info->fb_width, VT_FB_DEFAULT_WIDTH);
	info->fb_height = MIN(info->fb_height, VT_FB_DEFAULT_HEIGHT);

	vt_fb_init(vd);

	return (CN_INTERNAL);
}
Beispiel #4
0
static int
vt_efb_init(struct vt_device *vd)
{
	int		depth, d, disable, i, len;
	struct fb_info	*info;
	struct efi_fb	*efifb;
	caddr_t		kmdp;

	info = vd->vd_softc;

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

	kmdp = preload_search_by_type("elf kernel");
	if (kmdp == NULL)
		kmdp = preload_search_by_type("elf64 kernel");
        efifb = (struct efi_fb *)preload_search_info(kmdp,
            MODINFO_METADATA | MODINFOMD_EFI_FB);
	if (efifb == NULL)
		return (CN_DEAD);

	info->fb_height = efifb->fb_height;
	info->fb_width = efifb->fb_width;

	depth = fls(efifb->fb_mask_red);
	d = fls(efifb->fb_mask_green);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_blue);
	depth = d > depth ? d : depth;
	d = fls(efifb->fb_mask_reserved);
	depth = d > depth ? d : depth;
	info->fb_depth = depth;

	info->fb_stride = efifb->fb_stride * (depth / 8);

	vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB,
	    efifb->fb_mask_red, ffs(efifb->fb_mask_red) - 1,
	    efifb->fb_mask_green, ffs(efifb->fb_mask_green) - 1,
	    efifb->fb_mask_blue, ffs(efifb->fb_mask_blue) - 1);

	info->fb_size = info->fb_height * info->fb_stride;
	info->fb_pbase = efifb->fb_addr;
	/*
	 * We could use pmap_mapdev here except that the kernel pmap
	 * hasn't been created yet and hence any attempt to lock it will
	 * fail.
	 */
	info->fb_vbase = PHYS_TO_DMAP(efifb->fb_addr);

	/* 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;

	/*
	 * Early FB driver work with static window buffer, so reduce to minimal
	 * size, buffer or screen.
	 */
	info->fb_width = MIN(info->fb_width, VT_FB_DEFAULT_WIDTH);
	info->fb_height = MIN(info->fb_height, VT_FB_DEFAULT_HEIGHT);

	fb_probe(info);
	vt_fb_init(vd);


	return (CN_INTERNAL);
}