1a4a10b37SToomas Soome /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3a4a10b37SToomas Soome * 4a4a10b37SToomas Soome * Copyright (c) 2014 The FreeBSD Foundation 5a4a10b37SToomas Soome * 6a4a10b37SToomas Soome * This software was developed by Aleksandr Rybalko under sponsorship from the 7a4a10b37SToomas Soome * FreeBSD Foundation. 8a4a10b37SToomas Soome * 9a4a10b37SToomas Soome * Redistribution and use in source and binary forms, with or without 10a4a10b37SToomas Soome * modification, are permitted provided that the following conditions 11a4a10b37SToomas Soome * are met: 12a4a10b37SToomas Soome * 1. Redistributions of source code must retain the above copyright 13a4a10b37SToomas Soome * notice, this list of conditions and the following disclaimer. 14a4a10b37SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 15a4a10b37SToomas Soome * notice, this list of conditions and the following disclaimer in the 16a4a10b37SToomas Soome * documentation and/or other materials provided with the distribution. 17a4a10b37SToomas Soome * 18a4a10b37SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19a4a10b37SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20a4a10b37SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21a4a10b37SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22a4a10b37SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23a4a10b37SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24a4a10b37SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25a4a10b37SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26a4a10b37SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27a4a10b37SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28a4a10b37SToomas Soome * SUCH DAMAGE. 29a4a10b37SToomas Soome */ 30a4a10b37SToomas Soome 31a4a10b37SToomas Soome #include <sys/param.h> 32a4a10b37SToomas Soome #include <sys/systm.h> 33a4a10b37SToomas Soome #include <sys/kernel.h> 34a4a10b37SToomas Soome #include <sys/fbio.h> 35a4a10b37SToomas Soome #include <sys/linker.h> 36a4a10b37SToomas Soome 37a4a10b37SToomas Soome #include "opt_platform.h" 38a4a10b37SToomas Soome 39a4a10b37SToomas Soome #include <machine/metadata.h> 40a4a10b37SToomas Soome #include <machine/vmparam.h> 41a4a10b37SToomas Soome #include <vm/vm.h> 42a4a10b37SToomas Soome #include <vm/pmap.h> 43a4a10b37SToomas Soome 44a4a10b37SToomas Soome #include <dev/vt/vt.h> 45a4a10b37SToomas Soome #include <dev/vt/hw/fb/vt_fb.h> 46a4a10b37SToomas Soome #include <dev/vt/colors/vt_termcolors.h> 47a4a10b37SToomas Soome 48a4a10b37SToomas Soome static vd_init_t vt_vbefb_init; 498ebda6e4SGreg V static vd_fini_t vt_vbefb_fini; 50a4a10b37SToomas Soome static vd_probe_t vt_vbefb_probe; 51a4a10b37SToomas Soome 52a4a10b37SToomas Soome static struct vt_driver vt_vbefb_driver = { 53a4a10b37SToomas Soome .vd_name = "vbefb", 54a4a10b37SToomas Soome .vd_probe = vt_vbefb_probe, 55a4a10b37SToomas Soome .vd_init = vt_vbefb_init, 568ebda6e4SGreg V .vd_fini = vt_vbefb_fini, 57a4a10b37SToomas Soome .vd_blank = vt_fb_blank, 58a4a10b37SToomas Soome .vd_bitblt_text = vt_fb_bitblt_text, 59a4a10b37SToomas Soome .vd_invalidate_text = vt_fb_invalidate_text, 60a4a10b37SToomas Soome .vd_bitblt_bmp = vt_fb_bitblt_bitmap, 61b93028d8SEmmanuel Vadot .vd_bitblt_argb = vt_fb_bitblt_argb, 62a4a10b37SToomas Soome .vd_drawrect = vt_fb_drawrect, 63a4a10b37SToomas Soome .vd_setpixel = vt_fb_setpixel, 64a4a10b37SToomas Soome .vd_fb_ioctl = vt_fb_ioctl, 65a4a10b37SToomas Soome .vd_fb_mmap = vt_fb_mmap, 66a4a10b37SToomas Soome .vd_suspend = vt_suspend, 67a4a10b37SToomas Soome .vd_resume = vt_resume, 68a4a10b37SToomas Soome /* Better than VGA, but still generic driver. */ 69a4a10b37SToomas Soome .vd_priority = VD_PRIORITY_GENERIC + 1, 70a4a10b37SToomas Soome }; 71a4a10b37SToomas Soome 72a4a10b37SToomas Soome static struct fb_info local_vbe_info; 73a4a10b37SToomas Soome VT_DRIVER_DECLARE(vt_vbefb, vt_vbefb_driver); 74a4a10b37SToomas Soome 75a4a10b37SToomas Soome static int 76a4a10b37SToomas Soome vt_vbefb_probe(struct vt_device *vd) 77a4a10b37SToomas Soome { 78a4a10b37SToomas Soome int disabled; 79a4a10b37SToomas Soome struct vbe_fb *vbefb; 80a4a10b37SToomas Soome 81a4a10b37SToomas Soome disabled = 0; 82a4a10b37SToomas Soome TUNABLE_INT_FETCH("hw.syscons.disable", &disabled); 83a4a10b37SToomas Soome if (disabled != 0) 84a4a10b37SToomas Soome return (CN_DEAD); 85a4a10b37SToomas Soome 86*b72ae900SAhmad Khalifa vbefb = (struct vbe_fb *)preload_search_info(preload_kmdp, 87a4a10b37SToomas Soome MODINFO_METADATA | MODINFOMD_VBE_FB); 88a4a10b37SToomas Soome if (vbefb == NULL) 89a4a10b37SToomas Soome return (CN_DEAD); 90a4a10b37SToomas Soome 91a4a10b37SToomas Soome return (CN_INTERNAL); 92a4a10b37SToomas Soome } 93a4a10b37SToomas Soome 94a4a10b37SToomas Soome static int 95a4a10b37SToomas Soome vt_vbefb_init(struct vt_device *vd) 96a4a10b37SToomas Soome { 97a4a10b37SToomas Soome struct fb_info *info; 98a4a10b37SToomas Soome struct vbe_fb *vbefb; 99a4a10b37SToomas Soome int format, roff, goff, boff; 100a4a10b37SToomas Soome 101a4a10b37SToomas Soome info = vd->vd_softc; 102a4a10b37SToomas Soome if (info == NULL) 103a4a10b37SToomas Soome info = vd->vd_softc = (void *)&local_vbe_info; 104a4a10b37SToomas Soome 105*b72ae900SAhmad Khalifa vbefb = (struct vbe_fb *)preload_search_info(preload_kmdp, 106a4a10b37SToomas Soome MODINFO_METADATA | MODINFOMD_VBE_FB); 107a4a10b37SToomas Soome if (vbefb == NULL) 108a4a10b37SToomas Soome return (CN_DEAD); 109a4a10b37SToomas Soome 110a4a10b37SToomas Soome info->fb_height = vbefb->fb_height; 111a4a10b37SToomas Soome info->fb_width = vbefb->fb_width; 112a4a10b37SToomas Soome 113a4a10b37SToomas Soome info->fb_depth = vbefb->fb_bpp; 114a4a10b37SToomas Soome /* Round to a multiple of the bits in a byte. */ 115a4a10b37SToomas Soome info->fb_bpp = roundup2(vbefb->fb_bpp, NBBY); 116a4a10b37SToomas Soome 117a4a10b37SToomas Soome /* Stride in bytes, not pixels */ 118a4a10b37SToomas Soome info->fb_stride = vbefb->fb_stride * (info->fb_bpp / NBBY); 119a4a10b37SToomas Soome 120a4a10b37SToomas Soome if (info->fb_depth == 8) 121a4a10b37SToomas Soome format = COLOR_FORMAT_VGA; 122a4a10b37SToomas Soome else 123a4a10b37SToomas Soome format = COLOR_FORMAT_RGB; 124a4a10b37SToomas Soome 125a4a10b37SToomas Soome roff = ffs(vbefb->fb_mask_red) - 1; 126a4a10b37SToomas Soome goff = ffs(vbefb->fb_mask_green) - 1; 127a4a10b37SToomas Soome boff = ffs(vbefb->fb_mask_blue) - 1; 128b9f3b63aSLeandro Lupori vt_config_cons_colors(info, format, 129a4a10b37SToomas Soome vbefb->fb_mask_red >> roff, roff, 130a4a10b37SToomas Soome vbefb->fb_mask_green >> goff, goff, 131a4a10b37SToomas Soome vbefb->fb_mask_blue >> boff, boff); 132a4a10b37SToomas Soome 133a4a10b37SToomas Soome /* Mark cmap initialized. */ 134a4a10b37SToomas Soome info->fb_cmsize = NCOLORS; 135a4a10b37SToomas Soome 136a4a10b37SToomas Soome info->fb_size = info->fb_height * info->fb_stride; 137a4a10b37SToomas Soome info->fb_pbase = vbefb->fb_addr; 138a4a10b37SToomas Soome info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, 139a4a10b37SToomas Soome info->fb_size, VM_MEMATTR_WRITE_COMBINING); 140a4a10b37SToomas Soome 141a4a10b37SToomas Soome vt_fb_init(vd); 142a4a10b37SToomas Soome 143a4a10b37SToomas Soome return (CN_INTERNAL); 144a4a10b37SToomas Soome } 1458ebda6e4SGreg V 1468ebda6e4SGreg V static void 1478ebda6e4SGreg V vt_vbefb_fini(struct vt_device *vd, void *softc) 1488ebda6e4SGreg V { 1498ebda6e4SGreg V struct fb_info *info = softc; 1508ebda6e4SGreg V 1518ebda6e4SGreg V vt_fb_fini(vd, softc); 1527ae99f80SJohn Baldwin pmap_unmapdev((void *)info->fb_vbase, info->fb_size); 1538ebda6e4SGreg V } 154