Switch fb and efifb drivers to use names and new vt(4) driver probe method.
Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
33c335d9af
commit
cc38cb22e9
@ -51,35 +51,57 @@ __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;
|
||||
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, 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);
|
||||
if (info == NULL)
|
||||
info = vd->vd_softc = (void *)&local_info;
|
||||
|
||||
kmdp = preload_search_by_type("elf kernel");
|
||||
if (kmdp == NULL)
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 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 chosen, node;
|
||||
ihandle_t stdout;
|
||||
char type[64];
|
||||
phandle_t node;
|
||||
|
||||
if (vd->vd_softc == NULL)
|
||||
vd->vd_softc = (void *)&local_info;
|
||||
|
||||
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");
|
||||
}
|
||||
OF_getprop(node, "device_type", type, sizeof(type));
|
||||
if (strcmp(type, "display") != 0)
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
@ -184,6 +188,68 @@ 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;
|
||||
|
||||
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;
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user