diff options
author | ray <ray@FreeBSD.org> | 2014-05-05 21:48:19 +0000 |
---|---|---|
committer | ray <ray@FreeBSD.org> | 2014-05-05 21:48:19 +0000 |
commit | cc38cb22e907092934f43ebdcc910d0ac1ebd4d6 (patch) | |
tree | d21449cdd5e635add5de19422981ed5055395428 | |
parent | 33c335d9afb25bdeb054d9bea8222a45f4f25848 (diff) | |
download | FreeBSD-src-cc38cb22e907092934f43ebdcc910d0ac1ebd4d6.zip FreeBSD-src-cc38cb22e907092934f43ebdcc910d0ac1ebd4d6.tar.gz |
Switch fb and efifb drivers to use names and new vt(4) driver probe method.
Sponsored by: The FreeBSD Foundation
-rw-r--r-- | sys/dev/vt/hw/efifb/efifb.c | 53 | ||||
-rw-r--r-- | sys/dev/vt/hw/fb/vt_early_fb.c | 73 | ||||
-rw-r--r-- | sys/dev/vt/hw/fb/vt_fb.c | 66 | ||||
-rw-r--r-- | sys/dev/vt/hw/fb/vt_fb.h | 2 |
4 files changed, 157 insertions, 37 deletions
diff --git a/sys/dev/vt/hw/efifb/efifb.c b/sys/dev/vt/hw/efifb/efifb.c index 4a6eeb7..683cecb 100644 --- a/sys/dev/vt/hw/efifb/efifb.c +++ b/sys/dev/vt/hw/efifb/efifb.c @@ -51,36 +51,58 @@ __FBSDID("$FreeBSD$"); #include <dev/vt/hw/fb/vt_fb.h> #include <dev/vt/colors/vt_termcolors.h> -static vd_init_t vt_efb_init; +static vd_init_t vt_efifb_init; +static vd_probe_t vt_efifb_probe; -static struct vt_driver vt_efb_driver = { - .vd_init = vt_efb_init, +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, /* Better than VGA, but still generic driver. */ .vd_priority = VD_PRIORITY_GENERIC + 1, }; -static struct fb_info info; -VT_CONSDEV_DECLARE(vt_efb_driver, - MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)), - MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info); +static struct fb_info local_info; +VT_DRIVER_DECLARE(vt_efifb, vt_efifb_driver); static int -vt_efb_init(struct vt_device *vd) +vt_efifb_probe(struct vt_device *vd) { - int depth, d, disable, i, len; - struct fb_info *info; + int disabled; struct efi_fb *efifb; caddr_t kmdp; - info = vd->vd_softc; + disabled = 0; + TUNABLE_INT_FETCH("hw.syscons.disable", &disabled); + if (disabled != 0) + return (CN_DEAD); - disable = 0; - TUNABLE_INT_FETCH("hw.syscons.disable", &disable); - if (disable != 0) + 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, i, len; + 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"); @@ -136,7 +158,8 @@ vt_efb_init(struct vt_device *vd) fb_probe(info); vt_fb_init(vd); + /* Clear the screen. */ + vt_fb_blank(vd, TC_BLACK); return (CN_INTERNAL); } - diff --git a/sys/dev/vt/hw/fb/vt_early_fb.c b/sys/dev/vt/hw/fb/vt_early_fb.c index 4a81f4f..8ca2338 100644 --- a/sys/dev/vt/hw/fb/vt_early_fb.c +++ b/sys/dev/vt/hw/fb/vt_early_fb.c @@ -52,18 +52,19 @@ __FBSDID("$FreeBSD$"); #include <dev/vt/colors/vt_termcolors.h> 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 info; -VT_CONSDEV_DECLARE(vt_fb_early_driver, - MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)), - MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info); +static struct fb_info local_info; +VT_DRIVER_DECLARE(vt_efb, vt_fb_early_driver); static void #ifdef FDT @@ -126,30 +127,62 @@ vt_efb_initialize(struct fb_info *info) } } -static int -vt_efb_init(struct vt_device *vd) +static phandle_t +vt_efb_get_fbnode() { - struct ofw_pci_register pciaddrs[8]; - struct fb_info *info; - int i, len, n_pciaddrs; phandle_t chosen, node; ihandle_t stdout; char type[64]; - info = vd->vd_softc; - chosen = OF_finddevice("/chosen"); OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); node = OF_instance_to_package(stdout); - if (node == -1) { - /* - * The "/chosen/stdout" does not exist try - * using "screen" directly. - */ - node = OF_finddevice("screen"); + 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); } - OF_getprop(node, "device_type", type, sizeof(type)); - if (strcmp(type, "display") != 0) + /* 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) \ @@ -249,7 +282,6 @@ vt_efb_init(struct vt_device *vd) #endif } - /* blank full size */ len = info->fb_size / 4; for (i = 0; i < len; i++) { @@ -274,6 +306,5 @@ vt_efb_init(struct vt_device *vd) fb_probe(info); vt_fb_init(vd); - return (CN_INTERNAL); } diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c index 7163bdc..3ffba40 100644 --- a/sys/dev/vt/hw/fb/vt_fb.c +++ b/sys/dev/vt/hw/fb/vt_fb.c @@ -50,9 +50,11 @@ void vt_fb_drawrect(struct vt_device *vd, int x1, int y1, int x2, int y2, 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, @@ -61,6 +63,8 @@ static struct vt_driver vt_fb_driver = { .vd_fb_mmap = vt_fb_mmap, }; +VT_DRIVER_DECLARE(vt_fb, vt_fb_driver); + static int vt_fb_ioctl(struct vt_device *vd, u_long cmd, caddr_t data, struct thread *td) { @@ -189,6 +193,68 @@ vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask, 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; + + 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); + break; + case 2: + info->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); + break; + case 4: + info->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; diff --git a/sys/dev/vt/hw/fb/vt_fb.h b/sys/dev/vt/hw/fb/vt_fb.h index 9b3aa0d..10dd238 100644 --- a/sys/dev/vt/hw/fb/vt_fb.h +++ b/sys/dev/vt/hw/fb/vt_fb.h @@ -41,7 +41,7 @@ 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; - #endif /* _DEV_VT_HW_FB_VT_FB_H_ */ |