Index: stable/10/sys/dev/fb/fbd.c =================================================================== --- stable/10/sys/dev/fb/fbd.c (revision 271116) +++ stable/10/sys/dev/fb/fbd.c (revision 271117) @@ -1,469 +1,374 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Aleksandr Rybalko under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* Generic framebuffer */ /* TODO unlink from VT(9) */ /* TODO done normal /dev/fb methods */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include "fb_if.h" LIST_HEAD(fb_list_head_t, fb_list_entry) fb_list_head = LIST_HEAD_INITIALIZER(fb_list_head); struct fb_list_entry { struct fb_info *fb_info; struct cdev *fb_si; LIST_ENTRY(fb_list_entry) fb_list; }; struct fbd_softc { device_t sc_dev; struct fb_info *sc_info; }; static void fbd_evh_init(void *); /* SI_ORDER_SECOND, just after EVENTHANDLERs initialized. */ SYSINIT(fbd_evh_init, SI_SUB_CONFIGURE, SI_ORDER_SECOND, fbd_evh_init, NULL); static d_open_t fb_open; static d_close_t fb_close; static d_read_t fb_read; static d_write_t fb_write; static d_ioctl_t fb_ioctl; static d_mmap_t fb_mmap; static struct cdevsw fb_cdevsw = { .d_version = D_VERSION, .d_flags = D_NEEDGIANT, .d_open = fb_open, .d_close = fb_close, .d_read = fb_read, .d_write = fb_write, .d_ioctl = fb_ioctl, .d_mmap = fb_mmap, .d_name = "fb", }; static int framebuffer_dev_unit = 0; static int fb_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { return (0); } static int fb_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { return (0); } static int fb_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { struct fb_info *info; int error; error = 0; info = dev->si_drv1; switch (cmd) { case FBIOGTYPE: bcopy(info, (struct fbtype *)data, sizeof(struct fbtype)); break; case FBIO_GETWINORG: /* get frame buffer window origin */ *(u_int *)data = 0; break; case FBIO_GETDISPSTART: /* get display start address */ ((video_display_start_t *)data)->x = 0; ((video_display_start_t *)data)->y = 0; break; case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ *(u_int *)data = info->fb_stride; break; case FBIO_BLANK: /* blank display */ error = 0; /* TODO */ break; default: error = ENOIOCTL; break; } return (error); } static int fb_read(struct cdev *dev, struct uio *uio, int ioflag) { return (0); /* XXX nothing to read, yet */ } static int fb_write(struct cdev *dev, struct uio *uio, int ioflag) { return (0); /* XXX nothing written */ } static int fb_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) { struct fb_info *info; info = dev->si_drv1; + + if ((info->fb_flags & FB_FLAG_NOMMAP) || info->fb_pbase == 0) + return (ENODEV); + if (offset < info->fb_size) { *paddr = info->fb_pbase + offset; return (0); } return (EINVAL); } - -static void -vt_fb_mem_wr1(struct fb_info *sc, uint32_t o, uint8_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - *(uint8_t *)(sc->fb_vbase + o) = v; -} - -static void -vt_fb_mem_wr2(struct fb_info *sc, uint32_t o, uint16_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - *(uint16_t *)(sc->fb_vbase + o) = v; -} - -static void -vt_fb_mem_wr4(struct fb_info *sc, uint32_t o, uint32_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - *(uint32_t *)(sc->fb_vbase + o) = v; -} - -static void -vt_fb_mem_copy(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from, - uint32_t size) -{ - - memmove((void *)(sc->fb_vbase + offset_to), (void *)(sc->fb_vbase + - offset_from), size); -} - -static void -vt_fb_indir_wr1(struct fb_info *sc, uint32_t o, uint8_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - sc->fb_write(sc->fb_priv, o, &v, 1); -} - -static void -vt_fb_indir_wr2(struct fb_info *sc, uint32_t o, uint16_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - sc->fb_write(sc->fb_priv, o, &v, 2); -} - -static void -vt_fb_indir_wr4(struct fb_info *sc, uint32_t o, uint32_t v) -{ - - KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); - sc->fb_write(sc->fb_priv, o, &v, 4); -} - -static void -vt_fb_indir_copy(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from, - uint32_t size) -{ - - sc->copy(sc->fb_priv, offset_to, offset_from, size); -} - -int -fb_probe(struct fb_info *info) -{ - - if (info->fb_size == 0) - return (ENXIO); - - if (info->fb_write != NULL) { - if (info->fb_write == NULL) { - return (EINVAL); - } - info->fb_flags |= FB_FLAG_NOMMAP; - info->wr1 = &vt_fb_indir_wr1; - info->wr2 = &vt_fb_indir_wr2; - info->wr4 = &vt_fb_indir_wr4; - info->copy = &vt_fb_indir_copy; - } else if (info->fb_vbase != 0) { - if (info->fb_pbase == 0) { - info->fb_flags |= FB_FLAG_NOMMAP; - } - info->wr1 = &vt_fb_mem_wr1; - info->wr2 = &vt_fb_mem_wr2; - info->wr4 = &vt_fb_mem_wr4; - info->copy = &vt_fb_mem_copy; - } else - return (ENXIO); - - return (0); -} - - static int fb_init(struct fb_list_entry *entry, int unit) { struct fb_info *info; info = entry->fb_info; entry->fb_si = make_dev(&fb_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, "fb%d", unit); entry->fb_si->si_drv1 = info; info->fb_cdev = entry->fb_si; return (0); } int fbd_list() { struct fb_list_entry *entry; if (LIST_EMPTY(&fb_list_head)) return (ENOENT); LIST_FOREACH(entry, &fb_list_head, fb_list) { printf("FB %s @%p\n", entry->fb_info->fb_name, (void *)entry->fb_info->fb_pbase); } return (0); } static struct fb_list_entry * fbd_find(struct fb_info* info) { struct fb_list_entry *entry, *tmp; LIST_FOREACH_SAFE(entry, &fb_list_head, fb_list, tmp) { if (entry->fb_info == info) { return (entry); } } return (NULL); } int fbd_register(struct fb_info* info) { struct fb_list_entry *entry; int err, first; first = 0; if (LIST_EMPTY(&fb_list_head)) first++; entry = fbd_find(info); if (entry != NULL) { /* XXX Update framebuffer params */ return (0); } - err = fb_probe(info); - if (err) - return (err); - entry = malloc(sizeof(struct fb_list_entry), M_DEVBUF, M_WAITOK|M_ZERO); entry->fb_info = info; LIST_INSERT_HEAD(&fb_list_head, entry, fb_list); err = fb_init(entry, framebuffer_dev_unit++); if (err) return (err); - if (first) - vt_fb_attach(info); + if (first) { + if (vt_fb_attach(info) == CN_DEAD) + return (ENXIO); + } return (0); } int fbd_unregister(struct fb_info* info) { struct fb_list_entry *entry, *tmp; LIST_FOREACH_SAFE(entry, &fb_list_head, fb_list, tmp) { if (entry->fb_info == info) { LIST_REMOVE(entry, fb_list); free(entry, M_DEVBUF); return (0); } } return (ENOENT); } static void register_fb_wrap(void *arg, void *ptr) { fbd_register((struct fb_info *)ptr); } static void unregister_fb_wrap(void *arg, void *ptr) { fbd_unregister((struct fb_info *)ptr); } static void fbd_evh_init(void *ctx) { EVENTHANDLER_REGISTER(register_framebuffer, register_fb_wrap, NULL, EVENTHANDLER_PRI_ANY); EVENTHANDLER_REGISTER(unregister_framebuffer, unregister_fb_wrap, NULL, EVENTHANDLER_PRI_ANY); } /* Newbus methods. */ static int fbd_probe(device_t dev) { return (BUS_PROBE_NOWILDCARD); } static int fbd_attach(device_t dev) { struct fbd_softc *sc; int err; sc = device_get_softc(dev); sc->sc_dev = dev; sc->sc_info = FB_GETINFO(device_get_parent(dev)); if (sc->sc_info == NULL) return (ENXIO); err = fbd_register(sc->sc_info); return (err); } static int fbd_detach(device_t dev) { struct fbd_softc *sc; int err; sc = device_get_softc(dev); err = fbd_unregister(sc->sc_info); return (err); } static int fbd_suspend(device_t dev) { vt_fb_suspend(); return (bus_generic_suspend(dev)); } static int fbd_resume(device_t dev) { vt_fb_resume(); return (bus_generic_resume(dev)); } static device_method_t fbd_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fbd_probe), DEVMETHOD(device_attach, fbd_attach), DEVMETHOD(device_detach, fbd_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, fbd_suspend), DEVMETHOD(device_resume, fbd_resume), { 0, 0 } }; driver_t fbd_driver = { "fbd", fbd_methods, sizeof(struct fbd_softc) }; devclass_t fbd_devclass; DRIVER_MODULE(fbd, fb, fbd_driver, fbd_devclass, 0, 0); DRIVER_MODULE(fbd, drmn, fbd_driver, fbd_devclass, 0, 0); MODULE_VERSION(fbd, 1); Index: stable/10/sys/dev/vt/hw/efifb/efifb.c =================================================================== --- stable/10/sys/dev/vt/hw/efifb/efifb.c (revision 271116) +++ stable/10/sys/dev/vt/hw/efifb/efifb.c (revision 271117) @@ -1,183 +1,179 @@ /*- * Copyright (c) 2014 The FreeBSD Foundation * All rights reserved. * * This software was developed by Aleksandr Rybalko under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "opt_platform.h" #include #include #include #include #include #include #include #include #include static vd_init_t vt_efifb_init; static vd_probe_t vt_efifb_probe; static void vt_efifb_remap(void *efifb_data); static struct vt_driver vt_efifb_driver = { .vd_name = "efifb", .vd_probe = vt_efifb_probe, .vd_init = vt_efifb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, .vd_maskbitbltchr = vt_fb_maskbitbltchr, .vd_fb_ioctl = vt_fb_ioctl, .vd_fb_mmap = vt_fb_mmap, /* Better than VGA, but still generic driver. */ .vd_priority = VD_PRIORITY_GENERIC + 1, }; static struct fb_info local_info; VT_DRIVER_DECLARE(vt_efifb, vt_efifb_driver); SYSINIT(efifb_remap, SI_SUB_KMEM, SI_ORDER_ANY, vt_efifb_remap, &local_info); static int vt_efifb_probe(struct vt_device *vd) { int disabled; struct efi_fb *efifb; caddr_t kmdp; disabled = 0; TUNABLE_INT_FETCH("hw.syscons.disable", &disabled); if (disabled != 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); return (CN_INTERNAL); } 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); - fb_probe(info); vt_fb_init(vd); - - /* Clear the screen. */ - vt_fb_blank(vd, TC_BLACK); return (CN_INTERNAL); } static void vt_efifb_remap(void *xinfo) { struct fb_info *info = xinfo; if (info->fb_pbase == 0) return; /* * Remap as write-combining. This massively improves performance and * happens very early in kernel initialization, when everything is * still single-threaded and interrupts are off, so replacing the * mapping address is safe. */ info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, info->fb_size, VM_MEMATTR_WRITE_COMBINING); } Index: stable/10/sys/dev/vt/hw/fb/vt_early_fb.c =================================================================== --- stable/10/sys/dev/vt/hw/fb/vt_early_fb.c (revision 271116) +++ stable/10/sys/dev/vt/hw/fb/vt_early_fb.c (revision 271117) @@ -1,303 +1,302 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Aleksandr Rybalko under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "opt_platform.h" #ifdef FDT #include #include #include #include #include #endif #include #include #include static vd_init_t vt_efb_init; static vd_probe_t vt_efb_probe; static struct vt_driver vt_fb_early_driver = { .vd_name = "efb", .vd_probe = vt_efb_probe, .vd_init = vt_efb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, .vd_priority = VD_PRIORITY_GENERIC, }; static struct fb_info local_info; VT_DRIVER_DECLARE(vt_efb, vt_fb_early_driver); static void #ifdef FDT vt_efb_initialize(struct fb_info *info, phandle_t node) #else vt_efb_initialize(struct fb_info *info) #endif { #ifdef FDT char name[64]; cell_t retval; ihandle_t ih; int i; /* Open display device, thereby initializing it */ memset(name, 0, sizeof(name)); OF_package_to_path(node, name, sizeof(name)); ih = OF_open(name); #endif /* * Set up the color map */ switch (info->fb_depth) { case 8: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0); break; case 15: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0); break; case 16: vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0); break; case 24: case 32: #if BYTE_ORDER == BIG_ENDIAN vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); #else vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); #endif #ifdef FDT for (i = 0; i < 16; i++) { OF_call_method("color!", ih, 4, 1, (cell_t)((info->fb_cmap[i] >> 16) & 0xff), (cell_t)((info->fb_cmap[i] >> 8) & 0xff), (cell_t)((info->fb_cmap[i] >> 0) & 0xff), (cell_t)i, &retval); } #endif break; default: panic("Unknown color space fb_depth %d", info->fb_depth); break; } } static phandle_t vt_efb_get_fbnode() { phandle_t chosen, node; ihandle_t stdout; char type[64]; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); if (node != -1) { /* The "/chosen/stdout" present. */ OF_getprop(node, "device_type", type, sizeof(type)); /* Check if it has "display" type. */ if (strcmp(type, "display") == 0) return (node); } /* Try device with name "screen". */ node = OF_finddevice("screen"); return (node); } static int vt_efb_probe(struct vt_device *vd) { phandle_t node; node = vt_efb_get_fbnode(); if (node == -1) return (CN_DEAD); if ((OF_getproplen(node, "height") <= 0) || (OF_getproplen(node, "width") <= 0) || (OF_getproplen(node, "depth") <= 0) || (OF_getproplen(node, "linebytes") <= 0)) return (CN_DEAD); return (CN_INTERNAL); } 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 - fb_probe(info); vt_fb_init(vd); return (CN_INTERNAL); } Index: stable/10/sys/dev/vt/hw/fb/vt_fb.c =================================================================== --- stable/10/sys/dev/vt/hw/fb/vt_fb.c (revision 271116) +++ stable/10/sys/dev/vt/hw/fb/vt_fb.c (revision 271117) @@ -1,433 +1,471 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Aleksandr Rybalko under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include void vt_fb_drawrect(struct vt_device *vd, int x1, int y1, int x2, int y2, int fill, term_color_t color); void vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color); static struct vt_driver vt_fb_driver = { .vd_name = "fb", .vd_init = vt_fb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, .vd_maskbitbltchr = vt_fb_maskbitbltchr, .vd_drawrect = vt_fb_drawrect, .vd_setpixel = vt_fb_setpixel, .vd_postswitch = vt_fb_postswitch, .vd_priority = VD_PRIORITY_GENERIC+10, .vd_fb_ioctl = vt_fb_ioctl, .vd_fb_mmap = vt_fb_mmap, }; VT_DRIVER_DECLARE(vt_fb, vt_fb_driver); +static void +vt_fb_mem_wr1(struct fb_info *sc, uint32_t o, uint8_t v) +{ + + KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); + *(uint8_t *)(sc->fb_vbase + o) = v; +} + +static void +vt_fb_mem_wr2(struct fb_info *sc, uint32_t o, uint16_t v) +{ + + KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); + *(uint16_t *)(sc->fb_vbase + o) = v; +} + +static void +vt_fb_mem_wr4(struct fb_info *sc, uint32_t o, uint32_t v) +{ + + KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o)); + *(uint32_t *)(sc->fb_vbase + o) = v; +} + int vt_fb_ioctl(struct vt_device *vd, u_long cmd, caddr_t data, struct thread *td) { struct fb_info *info; int error = 0; info = vd->vd_softc; switch (cmd) { case FBIOGTYPE: bcopy(info, (struct fbtype *)data, sizeof(struct fbtype)); break; case FBIO_GETWINORG: /* get frame buffer window origin */ *(u_int *)data = 0; break; case FBIO_GETDISPSTART: /* get display start address */ ((video_display_start_t *)data)->x = 0; ((video_display_start_t *)data)->y = 0; break; case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ *(u_int *)data = info->fb_stride; break; case FBIO_BLANK: /* blank display */ if (vd->vd_driver->vd_blank == NULL) return (ENODEV); vd->vd_driver->vd_blank(vd, TC_BLACK); break; default: error = ENOIOCTL; break; } return (error); } int vt_fb_mmap(struct vt_device *vd, vm_ooffset_t offset, vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) { struct fb_info *info; info = vd->vd_softc; if (info->fb_flags & FB_FLAG_NOMMAP) return (ENODEV); if (offset >= 0 && offset < info->fb_size) { *paddr = info->fb_pbase + offset; #ifdef VM_MEMATTR_WRITE_COMBINING *memattr = VM_MEMATTR_WRITE_COMBINING; #endif return (0); } return (EINVAL); } void vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color) { struct fb_info *info; uint32_t c; u_int o; info = vd->vd_softc; c = info->fb_cmap[color]; o = info->fb_stride * y + x * FBTYPE_GET_BYTESPP(info); + KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer")); + switch (FBTYPE_GET_BYTESPP(info)) { case 1: - info->wr1(info, o, c); + vt_fb_mem_wr1(info, o, c); break; case 2: - info->wr2(info, o, c); + vt_fb_mem_wr2(info, o, c); break; case 3: - info->wr1(info, o, (c >> 16) & 0xff); - info->wr1(info, o + 1, (c >> 8) & 0xff); - info->wr1(info, o + 2, c & 0xff); + vt_fb_mem_wr1(info, o, (c >> 16) & 0xff); + vt_fb_mem_wr1(info, o + 1, (c >> 8) & 0xff); + vt_fb_mem_wr1(info, o + 2, c & 0xff); break; case 4: - info->wr4(info, o, c); + vt_fb_mem_wr4(info, o, c); break; default: /* panic? */ return; } } void vt_fb_drawrect(struct vt_device *vd, int x1, int y1, int x2, int y2, int fill, term_color_t color) { int x, y; for (y = y1; y <= y2; y++) { if (fill || (y == y1) || (y == y2)) { for (x = x1; x <= x2; x++) vt_fb_setpixel(vd, x, y, color); } else { vt_fb_setpixel(vd, x1, y, color); vt_fb_setpixel(vd, x2, y, color); } } } void vt_fb_blank(struct vt_device *vd, term_color_t color) { struct fb_info *info; uint32_t c; u_int o, h; info = vd->vd_softc; c = info->fb_cmap[color]; + KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer")); + switch (FBTYPE_GET_BYTESPP(info)) { case 1: for (h = 0; h < info->fb_height; h++) for (o = 0; o < info->fb_stride; o++) - info->wr1(info, h*info->fb_stride + o, c); + vt_fb_mem_wr1(info, h*info->fb_stride + o, c); break; case 2: for (h = 0; h < info->fb_height; h++) for (o = 0; o < info->fb_stride; o += 2) - info->wr2(info, h*info->fb_stride + o, c); + vt_fb_mem_wr2(info, h*info->fb_stride + o, c); break; case 3: for (h = 0; h < info->fb_height; h++) for (o = 0; o < info->fb_stride; o += 3) { - info->wr1(info, h*info->fb_stride + o, + vt_fb_mem_wr1(info, h*info->fb_stride + o, (c >> 16) & 0xff); - info->wr1(info, h*info->fb_stride + o + 1, + vt_fb_mem_wr1(info, h*info->fb_stride + o + 1, (c >> 8) & 0xff); - info->wr1(info, h*info->fb_stride + o + 2, + vt_fb_mem_wr1(info, h*info->fb_stride + o + 2, c & 0xff); } break; case 4: for (h = 0; h < info->fb_height; h++) for (o = 0; o < info->fb_stride; o += 4) - info->wr4(info, h*info->fb_stride + o, c); + vt_fb_mem_wr4(info, h*info->fb_stride + o, c); break; default: /* panic? */ return; } } void vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height, term_color_t fg, term_color_t bg) { struct fb_info *info; uint32_t fgc, bgc, cc, o; int c, l, bpp; u_long line; uint8_t b; const uint8_t *ch; info = vd->vd_softc; bpp = FBTYPE_GET_BYTESPP(info); fgc = info->fb_cmap[fg]; bgc = info->fb_cmap[bg]; b = 0; if (bpl == 0) bpl = (width + 7) >> 3; /* Bytes per sorce line. */ /* Don't try to put off screen pixels */ if (((left + width) > info->fb_width) || ((top + height) > info->fb_height)) return; + KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer")); + line = (info->fb_stride * top) + (left * bpp); for (l = 0; l < height; l++) { ch = src; for (c = 0; c < width; c++) { if (c % 8 == 0) b = *ch++; else b <<= 1; o = line + (c * bpp); cc = b & 0x80 ? fgc : bgc; switch(bpp) { case 1: - info->wr1(info, o, cc); + vt_fb_mem_wr1(info, o, cc); break; case 2: - info->wr2(info, o, cc); + vt_fb_mem_wr2(info, o, cc); break; case 3: /* Packed mode, so unaligned. Byte access. */ - info->wr1(info, o, (cc >> 16) & 0xff); - info->wr1(info, o + 1, (cc >> 8) & 0xff); - info->wr1(info, o + 2, cc & 0xff); + vt_fb_mem_wr1(info, o, (cc >> 16) & 0xff); + vt_fb_mem_wr1(info, o + 1, (cc >> 8) & 0xff); + vt_fb_mem_wr1(info, o + 2, cc & 0xff); break; case 4: - info->wr4(info, o, cc); + vt_fb_mem_wr4(info, o, cc); break; default: /* panic? */ break; } } line += info->fb_stride; src += bpl; } } void vt_fb_maskbitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height, term_color_t fg, term_color_t bg) { struct fb_info *info; uint32_t fgc, bgc, cc, o; int c, l, bpp; u_long line; uint8_t b, m; const uint8_t *ch; info = vd->vd_softc; bpp = FBTYPE_GET_BYTESPP(info); fgc = info->fb_cmap[fg]; bgc = info->fb_cmap[bg]; b = m = 0; if (bpl == 0) bpl = (width + 7) >> 3; /* Bytes per sorce line. */ /* Don't try to put off screen pixels */ if (((left + width) > info->fb_width) || ((top + height) > info->fb_height)) return; + KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer")); + line = (info->fb_stride * top) + (left * bpp); for (l = 0; l < height; l++) { ch = src; for (c = 0; c < width; c++) { if (c % 8 == 0) b = *ch++; else b <<= 1; if (mask != NULL) { if (c % 8 == 0) m = *mask++; else m <<= 1; /* Skip pixel write, if mask has no bit set. */ if ((m & 0x80) == 0) continue; } o = line + (c * bpp); cc = b & 0x80 ? fgc : bgc; switch(bpp) { case 1: - info->wr1(info, o, cc); + vt_fb_mem_wr1(info, o, cc); break; case 2: - info->wr2(info, o, cc); + vt_fb_mem_wr2(info, o, cc); break; case 3: /* Packed mode, so unaligned. Byte access. */ - info->wr1(info, o, (cc >> 16) & 0xff); - info->wr1(info, o + 1, (cc >> 8) & 0xff); - info->wr1(info, o + 2, cc & 0xff); + vt_fb_mem_wr1(info, o, (cc >> 16) & 0xff); + vt_fb_mem_wr1(info, o + 1, (cc >> 8) & 0xff); + vt_fb_mem_wr1(info, o + 2, cc & 0xff); break; case 4: - info->wr4(info, o, cc); + vt_fb_mem_wr4(info, o, cc); break; default: /* panic? */ break; } } line += info->fb_stride; src += bpl; } } void vt_fb_postswitch(struct vt_device *vd) { struct fb_info *info; info = vd->vd_softc; if (info->enter != NULL) info->enter(info->fb_priv); } static int vt_fb_init_cmap(uint32_t *cmap, int depth) { switch (depth) { case 8: return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0)); case 15: return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0)); case 16: return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0)); case 24: case 32: /* Ignore alpha. */ return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0)); default: return (1); } } int vt_fb_init(struct vt_device *vd) { struct fb_info *info; int err; info = vd->vd_softc; vd->vd_height = info->fb_height; vd->vd_width = info->fb_width; + + if (info->fb_size == 0) + return (CN_DEAD); + + if (info->fb_pbase == 0) + info->fb_flags |= FB_FLAG_NOMMAP; if (info->fb_cmsize <= 0) { err = vt_fb_init_cmap(info->fb_cmap, FBTYPE_GET_BPP(info)); if (err) return (CN_DEAD); info->fb_cmsize = 16; } /* Clear the screen. */ vd->vd_driver->vd_blank(vd, TC_BLACK); /* Wakeup screen. KMS need this. */ vt_fb_postswitch(vd); return (CN_INTERNAL); } int vt_fb_attach(struct fb_info *info) { vt_allocate(&vt_fb_driver, info); return (0); } void vt_fb_resume(void) { vt_resume(); } void vt_fb_suspend(void) { vt_suspend(); } Index: stable/10/sys/dev/vt/hw/fb/vt_fb.h =================================================================== --- stable/10/sys/dev/vt/hw/fb/vt_fb.h (revision 271116) +++ stable/10/sys/dev/vt/hw/fb/vt_fb.h (revision 271117) @@ -1,49 +1,47 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation * All rights reserved. * * This software was developed by Aleksandr Rybalko under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _DEV_VT_HW_FB_VT_FB_H_ #define _DEV_VT_HW_FB_VT_FB_H_ /* Generic framebuffer interface call vt_fb_attach to init VT(9) */ int vt_fb_attach(struct fb_info *info); void vt_fb_resume(void); void vt_fb_suspend(void); -int fb_probe(struct fb_info *info); - vd_init_t vt_fb_init; vd_blank_t vt_fb_blank; vd_bitbltchr_t vt_fb_bitbltchr; vd_maskbitbltchr_t vt_fb_maskbitbltchr; vd_postswitch_t vt_fb_postswitch; vd_fb_ioctl_t vt_fb_ioctl; vd_fb_mmap_t vt_fb_mmap; #endif /* _DEV_VT_HW_FB_VT_FB_H_ */ Index: stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c =================================================================== --- stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c (revision 271116) +++ stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c (revision 271117) @@ -1,407 +1,406 @@ /*- * Copyright (c) 2011 Nathan Whitehorn * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #ifdef __sparc64__ #include #endif #include #include #include struct ofwfb_softc { struct fb_info fb; phandle_t sc_node; ihandle_t sc_handle; bus_space_tag_t sc_memt; }; static vd_probe_t ofwfb_probe; static vd_init_t ofwfb_init; static vd_bitbltchr_t ofwfb_bitbltchr; static const struct vt_driver vt_ofwfb_driver = { .vd_name = "ofwfb", .vd_probe = ofwfb_probe, .vd_init = ofwfb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = ofwfb_bitbltchr, .vd_maskbitbltchr = ofwfb_bitbltchr, .vd_fb_ioctl = vt_fb_ioctl, .vd_fb_mmap = vt_fb_mmap, .vd_priority = VD_PRIORITY_GENERIC+1, }; static struct ofwfb_softc ofwfb_conssoftc; VT_DRIVER_DECLARE(vt_ofwfb, vt_ofwfb_driver); static int ofwfb_probe(struct vt_device *vd) { phandle_t chosen, node; ihandle_t stdout; char type[64]; 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 (CN_DEAD); /* Looks OK... */ return (CN_INTERNAL); } static void ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left, unsigned int width, unsigned int height, term_color_t fg, term_color_t bg) { struct fb_info *sc = vd->vd_softc; u_long line; uint32_t fgc, bgc; int c; uint8_t b, m; union { uint32_t l; uint8_t c[4]; } ch1, ch2; fgc = sc->fb_cmap[fg]; bgc = sc->fb_cmap[bg]; b = m = 0; /* Don't try to put off screen pixels */ if (((left + width) > vd->vd_width) || ((top + height) > vd->vd_height)) return; line = (sc->fb_stride * top) + left * sc->fb_bpp/8; if (mask == NULL && sc->fb_bpp == 8 && (width % 8 == 0)) { for (; height > 0; height--) { for (c = 0; c < width; c += 8) { b = *src++; /* * Assume that there is more background than * foreground in characters and init accordingly */ ch1.l = ch2.l = (bg << 24) | (bg << 16) | (bg << 8) | bg; /* * Calculate 2 x 4-chars at a time, and then * write these out. */ if (b & 0x80) ch1.c[0] = fg; if (b & 0x40) ch1.c[1] = fg; if (b & 0x20) ch1.c[2] = fg; if (b & 0x10) ch1.c[3] = fg; if (b & 0x08) ch2.c[0] = fg; if (b & 0x04) ch2.c[1] = fg; if (b & 0x02) ch2.c[2] = fg; if (b & 0x01) ch2.c[3] = fg; *(uint32_t *)(sc->fb_vbase + line + c) = ch1.l; *(uint32_t *)(sc->fb_vbase + line + c + 4) = ch2.l; } line += sc->fb_stride; } } else { for (; height > 0; height--) { for (c = 0; c < width; c++) { if (c % 8 == 0) b = *src++; else b <<= 1; if (mask != NULL) { if (c % 8 == 0) m = *mask++; else m <<= 1; /* Skip pixel write, if mask not set. */ if ((m & 0x80) == 0) continue; } switch(sc->fb_bpp) { case 8: *(uint8_t *)(sc->fb_vbase + line + c) = b & 0x80 ? fg : bg; break; case 32: *(uint32_t *)(sc->fb_vbase + line + 4*c) = (b & 0x80) ? fgc : bgc; break; default: /* panic? */ break; } } line += sc->fb_stride; } } } static void ofwfb_initialize(struct vt_device *vd) { struct ofwfb_softc *sc = vd->vd_softc; int i; cell_t retval; uint32_t oldpix; /* * Set up the color map */ switch (sc->fb.fb_bpp) { case 8: vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); for (i = 0; i < 16; i++) { OF_call_method("color!", sc->sc_handle, 4, 1, (cell_t)((sc->fb.fb_cmap[i] >> 16) & 0xff), (cell_t)((sc->fb.fb_cmap[i] >> 8) & 0xff), (cell_t)((sc->fb.fb_cmap[i] >> 0) & 0xff), (cell_t)i, &retval); } break; case 32: /* * We bypass the usual bus_space_() accessors here, mostly * for performance reasons. In particular, we don't want * any barrier operations that may be performed and handle * endianness slightly different. Figure out the host-view * endianness of the frame buffer. */ oldpix = bus_space_read_4(sc->sc_memt, sc->fb.fb_vbase, 0); bus_space_write_4(sc->sc_memt, sc->fb.fb_vbase, 0, 0xff000000); if (*(uint8_t *)(sc->fb.fb_vbase) == 0xff) vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); else vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); bus_space_write_4(sc->sc_memt, sc->fb.fb_vbase, 0, oldpix); break; default: panic("Unknown color space depth %d", sc->fb.fb_bpp); break; } sc->fb.fb_cmsize = 16; } static int ofwfb_init(struct vt_device *vd) { struct ofwfb_softc *sc; char type[64]; phandle_t chosen; phandle_t node; uint32_t depth, height, width, stride; uint32_t fb_phys; int i, len; #ifdef __sparc64__ static struct bus_space_tag ofwfb_memt[1]; bus_addr_t phys; int space; #endif /* Initialize softc */ vd->vd_softc = sc = &ofwfb_conssoftc; chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &sc->sc_handle, sizeof(ihandle_t)); node = OF_instance_to_package(sc->sc_handle); if (node == -1) { /* * The "/chosen/stdout" does not exist try * using "screen" directly. */ node = OF_finddevice("screen"); sc->sc_handle = OF_open("screen"); } OF_getprop(node, "device_type", type, sizeof(type)); if (strcmp(type, "display") != 0) return (CN_DEAD); /* Keep track of the OF node */ sc->sc_node = node; /* * Try to use a 32-bit framebuffer if possible. This may be * unimplemented and fail. That's fine -- it just means we are * stuck with the defaults. */ OF_call_method("set-depth", sc->sc_handle, 1, 1, (cell_t)32, &i); /* Make sure we have needed properties */ if (OF_getproplen(node, "height") != sizeof(height) || OF_getproplen(node, "width") != sizeof(width) || OF_getproplen(node, "depth") != sizeof(depth) || OF_getproplen(node, "linebytes") != sizeof(sc->fb.fb_stride)) return (CN_DEAD); /* Only support 8 and 32-bit framebuffers */ OF_getprop(node, "depth", &depth, sizeof(depth)); if (depth != 8 && depth != 32) return (CN_DEAD); sc->fb.fb_bpp = sc->fb.fb_depth = depth; OF_getprop(node, "height", &height, sizeof(height)); OF_getprop(node, "width", &width, sizeof(width)); OF_getprop(node, "linebytes", &stride, sizeof(stride)); sc->fb.fb_height = height; sc->fb.fb_width = width; sc->fb.fb_stride = stride; sc->fb.fb_size = sc->fb.fb_height * sc->fb.fb_stride; /* * 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(fb_phys)) { /* XXX We assume #address-cells is 1 at this point. */ OF_getprop(node, "address", &fb_phys, sizeof(fb_phys)); #if defined(__powerpc__) sc->sc_memt = &bs_be_tag; bus_space_map(sc->sc_memt, fb_phys, sc->fb.fb_size, BUS_SPACE_MAP_PREFETCHABLE, &sc->fb.fb_vbase); #elif defined(__sparc64__) OF_decode_addr(node, 0, &space, &phys); sc->sc_memt = &ofwfb_memt[0]; sc->fb.fb_vbase = sparc64_fake_bustag(space, fb_phys, sc->sc_memt); #elif defined(__arm__) sc->sc_memt = fdtbus_bs_tag; bus_space_map(sc->sc_memt, sc->fb.fb_pbase, sc->fb.fb_size, BUS_SPACE_MAP_PREFETCHABLE, (bus_space_handle_t *)&sc->fb.fb_vbase); #else #error Unsupported platform! #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. */ struct ofw_pci_register pciaddrs[8]; int num_pciaddrs = 0; /* * 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; num_pciaddrs = len / sizeof(struct ofw_pci_register); fb_phys = num_pciaddrs; for (i = 0; i < num_pciaddrs; i++) { /* If it is too small, not the framebuffer */ if (pciaddrs[i].size_lo < sc->fb.fb_stride * height) 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 */ fb_phys = i; /* If it is prefetchable, it certainly is */ if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) break; } if (fb_phys == num_pciaddrs) /* No candidates found */ return (CN_DEAD); #if defined(__powerpc__) OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->fb.fb_vbase); #elif defined(__sparc64__) OF_decode_addr(node, fb_phys, &space, &phys); sc->sc_memt = &ofwfb_memt[0]; sc->fb.fb_vbase = sparc64_fake_bustag(space, phys, sc->sc_memt); #else /* No ability to interpret assigned-addresses otherwise */ return (CN_DEAD); #endif } sc->fb.fb_pbase = fb_phys; ofwfb_initialize(vd); - fb_probe(&sc->fb); vt_fb_init(vd); return (CN_INTERNAL); } Index: stable/10/sys/powerpc/ps3/ps3_syscons.c =================================================================== --- stable/10/sys/powerpc/ps3/ps3_syscons.c (revision 271116) +++ stable/10/sys/powerpc/ps3/ps3_syscons.c (revision 271117) @@ -1,200 +1,196 @@ /*- * Copyright (c) 2011-2014 Nathan Whitehorn * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ps3-hvcall.h" #define PS3FB_SIZE (4*1024*1024) #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET 0x0100 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x0101 #define L1GPU_DISPLAY_SYNC_HSYNC 1 #define L1GPU_DISPLAY_SYNC_VSYNC 2 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102 static vd_init_t ps3fb_init; static vd_probe_t ps3fb_probe; void ps3fb_remap(void); struct ps3fb_softc { struct fb_info fb_info; uint64_t sc_fbhandle; uint64_t sc_fbcontext; uint64_t sc_dma_control; uint64_t sc_driver_info; uint64_t sc_reports; uint64_t sc_reports_size; }; static struct vt_driver vt_ps3fb_driver = { .vd_name = "ps3fb", .vd_probe = ps3fb_probe, .vd_init = ps3fb_init, .vd_blank = vt_fb_blank, .vd_bitbltchr = vt_fb_bitbltchr, .vd_maskbitbltchr = vt_fb_maskbitbltchr, .vd_fb_ioctl = vt_fb_ioctl, .vd_fb_mmap = vt_fb_mmap, /* Better than VGA, but still generic driver. */ .vd_priority = VD_PRIORITY_GENERIC + 1, }; VT_DRIVER_DECLARE(vt_ps3fb, vt_ps3fb_driver); static struct ps3fb_softc ps3fb_softc; static int ps3fb_probe(struct vt_device *vd) { struct ps3fb_softc *sc; int disable; char compatible[64]; #if 0 phandle_t root; #endif disable = 0; TUNABLE_INT_FETCH("hw.syscons.disable", &disable); if (disable != 0) return (0); sc = &ps3fb_softc; #if 0 root = OF_finddevice("/"); if (OF_getprop(root, "compatible", compatible, sizeof(compatible)) <= 0) return (0); if (strncmp(compatible, "sony,ps3", sizeof(compatible)) != 0) return (0); #else TUNABLE_STR_FETCH("hw.platform", compatible, sizeof(compatible)); if (strcmp(compatible, "ps3") != 0) return (CN_DEAD); #endif return (CN_INTERNAL); } void ps3fb_remap(void) { struct ps3fb_softc *sc; vm_offset_t va, fb_paddr; sc = &ps3fb_softc; lv1_gpu_close(); lv1_gpu_open(0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 0,0,0,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET, 0,0,1,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0); lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0); lv1_gpu_memory_allocate(PS3FB_SIZE, 0, 0, 0, 0, &sc->sc_fbhandle, &fb_paddr); lv1_gpu_context_allocate(sc->sc_fbhandle, 0, &sc->sc_fbcontext, &sc->sc_dma_control, &sc->sc_driver_info, &sc->sc_reports, &sc->sc_reports_size); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); sc->fb_info.fb_pbase = fb_paddr; for (va = 0; va < PS3FB_SIZE; va += PAGE_SIZE) pmap_kenter_attr(0x10000000 + va, fb_paddr + va, VM_MEMATTR_WRITE_COMBINING); } static int ps3fb_init(struct vt_device *vd) { struct ps3fb_softc *sc; /* Init softc */ vd->vd_softc = sc = &ps3fb_softc; /* XXX: get from HV repository */ sc->fb_info.fb_depth = 32; sc->fb_info.fb_height = 480; sc->fb_info.fb_width = 720; sc->fb_info.fb_stride = sc->fb_info.fb_width*4; sc->fb_info.fb_size = sc->fb_info.fb_height * sc->fb_info.fb_stride; sc->fb_info.fb_bpp = sc->fb_info.fb_stride / sc->fb_info.fb_width * 8; /* * The loader puts the FB at 0x10000000, so use that for now. */ sc->fb_info.fb_vbase = 0x10000000; /* 32-bit VGA palette */ vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); /* Set correct graphics context */ lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0); lv1_gpu_context_attribute(sc->sc_fbcontext, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0); - fb_probe(&sc->fb_info); - sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by fb_probe */ vt_fb_init(vd); - - /* Clear the screen. */ - vt_fb_blank(vd, TC_BLACK); + sc->fb_info.fb_flags &= ~FB_FLAG_NOMMAP; /* Set wrongly by vt_fb_init */ return (CN_INTERNAL); } Index: stable/10/sys/sys/fbio.h =================================================================== --- stable/10/sys/sys/fbio.h (revision 271116) +++ stable/10/sys/sys/fbio.h (revision 271117) @@ -1,639 +1,618 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software developed by the Computer Systems * Engineering group at Lawrence Berkeley Laboratory under DARPA * contract BG 91-66 and contributed to Berkeley. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)fbio.h 8.2 (Berkeley) 10/30/93 * * $FreeBSD$ */ #ifndef _SYS_FBIO_H_ #define _SYS_FBIO_H_ #ifndef _KERNEL #include #else #include #include #include #endif #include /* * Frame buffer ioctls (from Sprite, trimmed to essentials for X11). */ /* * Frame buffer type codes. */ #define FBTYPE_SUN1BW 0 /* multibus mono */ #define FBTYPE_SUN1COLOR 1 /* multibus color */ #define FBTYPE_SUN2BW 2 /* memory mono */ #define FBTYPE_SUN2COLOR 3 /* color w/rasterop chips */ #define FBTYPE_SUN2GP 4 /* GP1/GP2 */ #define FBTYPE_SUN5COLOR 5 /* RoadRunner accelerator */ #define FBTYPE_SUN3COLOR 6 /* memory color */ #define FBTYPE_MEMCOLOR 7 /* memory 24-bit */ #define FBTYPE_SUN4COLOR 8 /* memory color w/overlay */ #define FBTYPE_NOTSUN1 9 /* reserved for customer */ #define FBTYPE_NOTSUN2 10 /* reserved for customer */ #define FBTYPE_PCIMISC 11 /* (generic) PCI misc. disp. */ #define FBTYPE_SUNFAST_COLOR 12 /* accelerated 8bit */ #define FBTYPE_SUNROP_COLOR 13 /* MEMCOLOR with rop h/w */ #define FBTYPE_SUNFB_VIDEO 14 /* Simple video mixing */ #define FBTYPE_RESERVED5 15 /* reserved, do not use */ #define FBTYPE_RESERVED4 16 /* reserved, do not use */ #define FBTYPE_SUNGP3 17 #define FBTYPE_SUNGT 18 #define FBTYPE_SUNLEO 19 /* zx Leo */ #define FBTYPE_MDA 20 #define FBTYPE_HERCULES 21 #define FBTYPE_CGA 22 #define FBTYPE_EGA 23 #define FBTYPE_VGA 24 #define FBTYPE_PC98 25 #define FBTYPE_TGA 26 #define FBTYPE_TGA2 27 #define FBTYPE_MDICOLOR 28 /* cg14 */ #define FBTYPE_TCXCOLOR 29 /* SUNW,tcx */ #define FBTYPE_CREATOR 30 #define FBTYPE_LASTPLUSONE 31 /* max number of fbs (change as add) */ /* * Frame buffer descriptor as returned by FBIOGTYPE. */ struct fbtype { int fb_type; /* as defined above */ int fb_height; /* in pixels */ int fb_width; /* in pixels */ int fb_depth; /* bits per pixel */ int fb_cmsize; /* size of color map (entries) */ int fb_size; /* total size in bytes */ }; #define FBIOGTYPE _IOR('F', 0, struct fbtype) #define FBTYPE_GET_STRIDE(_fb) ((_fb)->fb_size / (_fb)->fb_height) #define FBTYPE_GET_BPP(_fb) ((_fb)->fb_bpp) #define FBTYPE_GET_BYTESPP(_fb) ((_fb)->fb_bpp / 8) #ifdef _KERNEL struct fb_info; typedef int fb_enter_t(void *priv); typedef int fb_leave_t(void *priv); -typedef int fb_write_t(void *priv, int offset, void *data, int size); -typedef int fb_read_t(void *priv, int offset, void *data, int size); -/* XXX: should use priv instead of fb_info too. */ -typedef void fb_copy_t(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from, - uint32_t size); -typedef void fb_wr1_t(struct fb_info *sc, uint32_t offset, uint8_t value); -typedef void fb_wr2_t(struct fb_info *sc, uint32_t offset, uint16_t value); -typedef void fb_wr4_t(struct fb_info *sc, uint32_t offset, uint32_t value); - -typedef int fb_ioctl_t(struct cdev *, u_long, caddr_t, int, struct thread *); -typedef int fb_mmap_t(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot, vm_memattr_t *memattr); - struct fb_info { /* Raw copy of fbtype. Do not change. */ int fb_type; /* as defined above */ int fb_height; /* in pixels */ int fb_width; /* in pixels */ int fb_depth; /* bits to define color */ int fb_cmsize; /* size of color map (entries) */ int fb_size; /* total size in bytes */ - /* Methods. */ - fb_write_t *fb_write; /* if NULL, direct mem write. */ - fb_read_t *fb_read; /* if NULL, direct mem read. */ - struct cdev *fb_cdev; - fb_wr1_t *wr1; - fb_wr2_t *wr2; - fb_wr4_t *wr4; - fb_copy_t *copy; fb_enter_t *enter; fb_leave_t *leave; intptr_t fb_pbase; /* For FB mmap. */ intptr_t fb_vbase; /* if NULL, use fb_write/fb_read. */ void *fb_priv; /* First argument for read/write. */ const char *fb_name; uint32_t fb_flags; int fb_stride; int fb_bpp; /* bits per pixel */ #define FB_FLAG_NOMMAP 1 /* mmap unsupported. */ uint32_t fb_cmap[16]; }; int fbd_list(void); int fbd_register(struct fb_info *); int fbd_unregister(struct fb_info *); static inline int register_framebuffer(struct fb_info *info) { EVENTHANDLER_INVOKE(register_framebuffer, info); return (0); } static inline int unregister_framebuffer(struct fb_info *info) { EVENTHANDLER_INVOKE(unregister_framebuffer, info); return (0); } #endif #ifdef notdef /* * General purpose structure for passing info in and out of frame buffers * (used for gp1) -- unsupported. */ struct fbinfo { int fb_physaddr; /* physical frame buffer address */ int fb_hwwidth; /* fb board width */ int fb_hwheight; /* fb board height */ int fb_addrdelta; /* phys addr diff between boards */ u_char *fb_ropaddr; /* fb virtual addr */ int fb_unit; /* minor devnum of fb */ }; #define FBIOGINFO _IOR('F', 2, struct fbinfo) #endif /* * Color map I/O. */ struct fbcmap { int index; /* first element (0 origin) */ int count; /* number of elements */ u_char *red; /* red color map elements */ u_char *green; /* green color map elements */ u_char *blue; /* blue color map elements */ }; #define FBIOPUTCMAP _IOW('F', 3, struct fbcmap) #define FBIOGETCMAP _IOW('F', 4, struct fbcmap) /* * Set/get attributes. */ #define FB_ATTR_NDEVSPECIFIC 8 /* no. of device specific values */ #define FB_ATTR_NEMUTYPES 4 /* no. of emulation types */ struct fbsattr { int flags; /* flags; see below */ int emu_type; /* emulation type (-1 if unused) */ int dev_specific[FB_ATTR_NDEVSPECIFIC]; /* catchall */ }; #define FB_ATTR_AUTOINIT 1 /* emulation auto init flag */ #define FB_ATTR_DEVSPECIFIC 2 /* dev. specific stuff valid flag */ struct fbgattr { int real_type; /* real device type */ int owner; /* PID of owner, 0 if myself */ struct fbtype fbtype; /* fbtype info for real device */ struct fbsattr sattr; /* see above */ int emu_types[FB_ATTR_NEMUTYPES]; /* possible emulations */ /* (-1 if unused) */ }; #define FBIOSATTR _IOW('F', 5, struct fbsattr) #define FBIOGATTR _IOR('F', 6, struct fbgattr) /* * Video control. */ #define FBVIDEO_OFF 0 #define FBVIDEO_ON 1 #define FBIOSVIDEO _IOW('F', 7, int) #define FBIOGVIDEO _IOR('F', 8, int) /* vertical retrace */ #define FBIOVERTICAL _IO('F', 9) /* * Hardware cursor control (for, e.g., CG6). A rather complex and icky * interface that smells like VMS, but there it is.... */ struct fbcurpos { short x; short y; }; struct fbcursor { short set; /* flags; see below */ short enable; /* nonzero => cursor on, 0 => cursor off */ struct fbcurpos pos; /* position on display */ struct fbcurpos hot; /* hot-spot within cursor */ struct fbcmap cmap; /* cursor color map */ struct fbcurpos size; /* number of valid bits in image & mask */ caddr_t image; /* cursor image bits */ caddr_t mask; /* cursor mask bits */ }; #define FB_CUR_SETCUR 0x01 /* set on/off (i.e., obey fbcursor.enable) */ #define FB_CUR_SETPOS 0x02 /* set position */ #define FB_CUR_SETHOT 0x04 /* set hot-spot */ #define FB_CUR_SETCMAP 0x08 /* set cursor color map */ #define FB_CUR_SETSHAPE 0x10 /* set size & bits */ #define FB_CUR_SETALL (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT | \ FB_CUR_SETCMAP | FB_CUR_SETSHAPE) /* controls for cursor attributes & shape (including position) */ #define FBIOSCURSOR _IOW('F', 24, struct fbcursor) #define FBIOGCURSOR _IOWR('F', 25, struct fbcursor) /* controls for cursor position only */ #define FBIOSCURPOS _IOW('F', 26, struct fbcurpos) #define FBIOGCURPOS _IOW('F', 27, struct fbcurpos) /* get maximum cursor size */ #define FBIOGCURMAX _IOR('F', 28, struct fbcurpos) /* * Video board information */ struct brd_info { u_short accessible_width; /* accessible bytes in scanline */ u_short accessible_height; /* number of accessible scanlines */ u_short line_bytes; /* number of bytes/scanline */ u_short hdb_capable; /* can this thing hardware db? */ u_short vmsize; /* video memory size */ u_char boardrev; /* board revision # */ u_char pad0; u_long pad1; }; #define FBIOGXINFO _IOR('F', 39, struct brd_info) /* * Monitor information */ struct mon_info { u_long mon_type; /* bit array */ #define MON_TYPE_STEREO 0x8 /* stereo display */ #define MON_TYPE_0_OFFSET 0x4 /* black level 0 ire instead of 7.5 */ #define MON_TYPE_OVERSCAN 0x2 /* overscan */ #define MON_TYPE_GRAY 0x1 /* greyscale monitor */ u_long pixfreq; /* pixel frequency in Hz */ u_long hfreq; /* horizontal freq in Hz */ u_long vfreq; /* vertical freq in Hz */ u_long vsync; /* vertical sync in scanlines */ u_long hsync; /* horizontal sync in pixels */ /* these are in pixel units */ u_short hfporch; /* horizontal front porch */ u_short hbporch; /* horizontal back porch */ u_short vfporch; /* vertical front porch */ u_short vbporch; /* vertical back porch */ }; #define FBIOMONINFO _IOR('F', 40, struct mon_info) /* * Color map I/O. */ struct fbcmap_i { unsigned int flags; #define FB_CMAP_BLOCK (1 << 0) /* wait for vertical refresh */ #define FB_CMAP_KERNEL (1 << 1) /* called within kernel */ int id; /* color map id */ int index; /* first element (0 origin) */ int count; /* number of elements */ u_char *red; /* red color map elements */ u_char *green; /* green color map elements */ u_char *blue; /* blue color map elements */ }; #define FBIOPUTCMAPI _IOW('F', 41, struct fbcmap_i) #define FBIOGETCMAPI _IOW('F', 42, struct fbcmap_i) /* The new style frame buffer ioctls. */ /* video mode information block */ struct video_info { int vi_mode; /* mode number, see below */ int vi_flags; #define V_INFO_COLOR (1 << 0) #define V_INFO_GRAPHICS (1 << 1) #define V_INFO_LINEAR (1 << 2) #define V_INFO_VESA (1 << 3) #define V_INFO_NONVGA (1 << 4) int vi_width; int vi_height; int vi_cwidth; int vi_cheight; int vi_depth; int vi_planes; vm_offset_t vi_window; /* physical address */ size_t vi_window_size; size_t vi_window_gran; vm_offset_t vi_buffer; /* physical address */ size_t vi_buffer_size; int vi_mem_model; #define V_INFO_MM_OTHER (-1) #define V_INFO_MM_TEXT 0 #define V_INFO_MM_PLANAR 1 #define V_INFO_MM_PACKED 2 #define V_INFO_MM_DIRECT 3 #define V_INFO_MM_CGA 100 #define V_INFO_MM_HGC 101 #define V_INFO_MM_VGAX 102 /* for MM_PACKED and MM_DIRECT only */ int vi_pixel_size; /* in bytes */ /* for MM_DIRECT only */ int vi_pixel_fields[4]; /* RGB and reserved fields */ int vi_pixel_fsizes[4]; /* reserved */ u_char vi_reserved[64]; vm_offset_t vi_registers; /* physical address */ vm_offset_t vi_registers_size; }; typedef struct video_info video_info_t; /* adapter infromation block */ struct video_adapter { int va_index; int va_type; #define KD_OTHER 0 /* unknown */ #define KD_MONO 1 /* monochrome adapter */ #define KD_HERCULES 2 /* hercules adapter */ #define KD_CGA 3 /* color graphics adapter */ #define KD_EGA 4 /* enhanced graphics adapter */ #define KD_VGA 5 /* video graphics adapter */ #define KD_PC98 6 /* PC-98 display */ #define KD_TGA 7 /* TGA */ #define KD_TGA2 8 /* TGA2 */ char *va_name; int va_unit; int va_minor; int va_flags; #define V_ADP_COLOR (1 << 0) #define V_ADP_MODECHANGE (1 << 1) #define V_ADP_STATESAVE (1 << 2) #define V_ADP_STATELOAD (1 << 3) #define V_ADP_FONT (1 << 4) #define V_ADP_PALETTE (1 << 5) #define V_ADP_BORDER (1 << 6) #define V_ADP_VESA (1 << 7) #define V_ADP_BOOTDISPLAY (1 << 8) #define V_ADP_PROBED (1 << 16) #define V_ADP_INITIALIZED (1 << 17) #define V_ADP_REGISTERED (1 << 18) #define V_ADP_ATTACHED (1 << 19) #define V_ADP_DAC8 (1 << 20) vm_offset_t va_io_base; int va_io_size; vm_offset_t va_crtc_addr; vm_offset_t va_mem_base; int va_mem_size; vm_offset_t va_window; /* virtual address */ size_t va_window_size; size_t va_window_gran; u_int va_window_orig; vm_offset_t va_buffer; /* virtual address */ size_t va_buffer_size; int va_initial_mode; int va_initial_bios_mode; int va_mode; struct video_info va_info; int va_line_width; struct { int x; int y; } va_disp_start; void *va_token; int va_model; int va_little_bitian; int va_little_endian; int va_buffer_alias; vm_offset_t va_registers; /* virtual address */ vm_offset_t va_registers_size; }; typedef struct video_adapter video_adapter_t; struct video_adapter_info { int va_index; int va_type; char va_name[16]; int va_unit; int va_flags; vm_offset_t va_io_base; int va_io_size; vm_offset_t va_crtc_addr; vm_offset_t va_mem_base; int va_mem_size; vm_offset_t va_window; /* virtual address */ size_t va_window_size; size_t va_window_gran; vm_offset_t va_unused0; size_t va_buffer_size; int va_initial_mode; int va_initial_bios_mode; int va_mode; int va_line_width; struct { int x; int y; } va_disp_start; u_int va_window_orig; /* reserved */ u_char va_reserved[64]; }; typedef struct video_adapter_info video_adapter_info_t; /* some useful video adapter index */ #define V_ADP_PRIMARY 0 #define V_ADP_SECONDARY 1 /* video mode numbers */ #define M_B40x25 0 /* black & white 40 columns */ #define M_C40x25 1 /* color 40 columns */ #define M_B80x25 2 /* black & white 80 columns */ #define M_C80x25 3 /* color 80 columns */ #define M_BG320 4 /* black & white graphics 320x200 */ #define M_CG320 5 /* color graphics 320x200 */ #define M_BG640 6 /* black & white graphics 640x200 hi-res */ #define M_EGAMONO80x25 7 /* ega-mono 80x25 */ #define M_CG320_D 13 /* ega mode D */ #define M_CG640_E 14 /* ega mode E */ #define M_EGAMONOAPA 15 /* ega mode F */ #define M_CG640x350 16 /* ega mode 10 */ #define M_ENHMONOAPA2 17 /* ega mode F with extended memory */ #define M_ENH_CG640 18 /* ega mode 10* */ #define M_ENH_B40x25 19 /* ega enhanced black & white 40 columns */ #define M_ENH_C40x25 20 /* ega enhanced color 40 columns */ #define M_ENH_B80x25 21 /* ega enhanced black & white 80 columns */ #define M_ENH_C80x25 22 /* ega enhanced color 80 columns */ #define M_VGA_C40x25 23 /* vga 8x16 font on color */ #define M_VGA_C80x25 24 /* vga 8x16 font on color */ #define M_VGA_M80x25 25 /* vga 8x16 font on mono */ #define M_VGA11 26 /* vga 640x480 2 colors */ #define M_BG640x480 26 #define M_VGA12 27 /* vga 640x480 16 colors */ #define M_CG640x480 27 #define M_VGA13 28 /* vga 320x200 256 colors */ #define M_VGA_CG320 28 #define M_VGA_C80x50 30 /* vga 8x8 font on color */ #define M_VGA_M80x50 31 /* vga 8x8 font on color */ #define M_VGA_C80x30 32 /* vga 8x16 font on color */ #define M_VGA_M80x30 33 /* vga 8x16 font on color */ #define M_VGA_C80x60 34 /* vga 8x8 font on color */ #define M_VGA_M80x60 35 /* vga 8x8 font on color */ #define M_VGA_CG640 36 /* vga 640x400 256 color */ #define M_VGA_MODEX 37 /* vga 320x240 256 color */ #define M_VGA_C90x25 40 /* vga 8x16 font on color */ #define M_VGA_M90x25 41 /* vga 8x16 font on mono */ #define M_VGA_C90x30 42 /* vga 8x16 font on color */ #define M_VGA_M90x30 43 /* vga 8x16 font on mono */ #define M_VGA_C90x43 44 /* vga 8x8 font on color */ #define M_VGA_M90x43 45 /* vga 8x8 font on mono */ #define M_VGA_C90x50 46 /* vga 8x8 font on color */ #define M_VGA_M90x50 47 /* vga 8x8 font on mono */ #define M_VGA_C90x60 48 /* vga 8x8 font on color */ #define M_VGA_M90x60 49 /* vga 8x8 font on mono */ #define M_ENH_B80x43 0x70 /* ega black & white 80x43 */ #define M_ENH_C80x43 0x71 /* ega color 80x43 */ #define M_PC98_80x25 98 /* PC98 text 80x25 */ #define M_PC98_80x30 99 /* PC98 text 80x30 */ #define M_PC98_EGC640x400 100 /* PC98 graphic 640x400 16 colors */ #define M_PC98_PEGC640x400 101 /* PC98 graphic 640x400 256 colors */ #define M_PC98_PEGC640x480 102 /* PC98 graphic 640x480 256 colors */ #define M_HGC_P0 0xe0 /* hercules graphics - page 0 @ B0000 */ #define M_HGC_P1 0xe1 /* hercules graphics - page 1 @ B8000 */ #define M_MCA_MODE 0xff /* monochrome adapter mode */ #define M_TEXT_80x25 200 /* generic text modes */ #define M_TEXT_80x30 201 #define M_TEXT_80x43 202 #define M_TEXT_80x50 203 #define M_TEXT_80x60 204 #define M_TEXT_132x25 205 #define M_TEXT_132x30 206 #define M_TEXT_132x43 207 #define M_TEXT_132x50 208 #define M_TEXT_132x60 209 #define M_VESA_BASE 0x100 /* VESA mode number base */ #define M_VESA_CG640x400 0x100 /* 640x400, 256 color */ #define M_VESA_CG640x480 0x101 /* 640x480, 256 color */ #define M_VESA_800x600 0x102 /* 800x600, 16 color */ #define M_VESA_CG800x600 0x103 /* 800x600, 256 color */ #define M_VESA_1024x768 0x104 /* 1024x768, 16 color */ #define M_VESA_CG1024x768 0x105 /* 1024x768, 256 color */ #define M_VESA_1280x1024 0x106 /* 1280x1024, 16 color */ #define M_VESA_CG1280x1024 0x107 /* 1280x1024, 256 color */ #define M_VESA_C80x60 0x108 /* 8x8 font */ #define M_VESA_C132x25 0x109 /* 8x16 font */ #define M_VESA_C132x43 0x10a /* 8x14 font */ #define M_VESA_C132x50 0x10b /* 8x8 font */ #define M_VESA_C132x60 0x10c /* 8x8 font */ #define M_VESA_32K_320 0x10d /* 320x200, 5:5:5 */ #define M_VESA_64K_320 0x10e /* 320x200, 5:6:5 */ #define M_VESA_FULL_320 0x10f /* 320x200, 8:8:8 */ #define M_VESA_32K_640 0x110 /* 640x480, 5:5:5 */ #define M_VESA_64K_640 0x111 /* 640x480, 5:6:5 */ #define M_VESA_FULL_640 0x112 /* 640x480, 8:8:8 */ #define M_VESA_32K_800 0x113 /* 800x600, 5:5:5 */ #define M_VESA_64K_800 0x114 /* 800x600, 5:6:5 */ #define M_VESA_FULL_800 0x115 /* 800x600, 8:8:8 */ #define M_VESA_32K_1024 0x116 /* 1024x768, 5:5:5 */ #define M_VESA_64K_1024 0x117 /* 1024x768, 5:6:5 */ #define M_VESA_FULL_1024 0x118 /* 1024x768, 8:8:8 */ #define M_VESA_32K_1280 0x119 /* 1280x1024, 5:5:5 */ #define M_VESA_64K_1280 0x11a /* 1280x1024, 5:6:5 */ #define M_VESA_FULL_1280 0x11b /* 1280x1024, 8:8:8 */ #define M_VESA_MODE_MAX 0x1ff struct video_display_start { int x; int y; }; typedef struct video_display_start video_display_start_t; struct video_color_palette { int index; /* first element (zero-based) */ int count; /* number of elements */ u_char *red; /* red */ u_char *green; /* green */ u_char *blue; /* blue */ u_char *transparent; /* may be NULL */ }; typedef struct video_color_palette video_color_palette_t; /* adapter info. */ #define FBIO_ADAPTER _IOR('F', 100, int) #define FBIO_ADPTYPE _IOR('F', 101, int) #define FBIO_ADPINFO _IOR('F', 102, struct video_adapter_info) /* video mode control */ #define FBIO_MODEINFO _IOWR('F', 103, struct video_info) #define FBIO_FINDMODE _IOWR('F', 104, struct video_info) #define FBIO_GETMODE _IOR('F', 105, int) #define FBIO_SETMODE _IOW('F', 106, int) /* get/set frame buffer window origin */ #define FBIO_GETWINORG _IOR('F', 107, u_int) #define FBIO_SETWINORG _IOW('F', 108, u_int) /* get/set display start address */ #define FBIO_GETDISPSTART _IOR('F', 109, video_display_start_t) #define FBIO_SETDISPSTART _IOW('F', 110, video_display_start_t) /* get/set scan line width */ #define FBIO_GETLINEWIDTH _IOR('F', 111, u_int) #define FBIO_SETLINEWIDTH _IOW('F', 112, u_int) /* color palette control */ #define FBIO_GETPALETTE _IOW('F', 113, video_color_palette_t) #define FBIO_SETPALETTE _IOW('F', 114, video_color_palette_t) /* blank display */ #define V_DISPLAY_ON 0 #define V_DISPLAY_BLANK 1 #define V_DISPLAY_STAND_BY 2 #define V_DISPLAY_SUSPEND 3 #define FBIO_BLANK _IOW('F', 115, int) #endif /* !_SYS_FBIO_H_ */ Index: stable/10 =================================================================== --- stable/10 (revision 271116) +++ stable/10 (revision 271117) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r268472,269620