[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 3/8] xen: introduce a generic framebuffer driver
On Mon, 10 Dec 2012, Jan Beulich wrote: > >>> On 07.12.12 at 19:02, Stefano Stabellini > >>> <stefano.stabellini@xxxxxxxxxxxxx> > wrote: > > Abstract away from vesa.c the funcions to handle a linear framebuffer > > and print characters to it. > > The corresponding functions are going to be removed from vesa.c in the > > next patch. > > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > > --- > > xen/drivers/video/Makefile | 1 + > > xen/drivers/video/fb.c | 209 > > ++++++++++++++++++++++++++++++++++++++++++++ > > xen/drivers/video/fb.h | 49 ++++++++++ > > 3 files changed, 259 insertions(+), 0 deletions(-) > > create mode 100644 xen/drivers/video/fb.c > > create mode 100644 xen/drivers/video/fb.h > > > > diff --git a/xen/drivers/video/Makefile b/xen/drivers/video/Makefile > > index 2993c39..3b3eb43 100644 > > --- a/xen/drivers/video/Makefile > > +++ b/xen/drivers/video/Makefile > > @@ -2,4 +2,5 @@ obj-$(HAS_VGA) := vga.o > > obj-$(HAS_VIDEO) += font_8x14.o > > obj-$(HAS_VIDEO) += font_8x16.o > > obj-$(HAS_VIDEO) += font_8x8.o > > +obj-$(HAS_VIDEO) += fb.o > > obj-$(HAS_VGA) += vesa.o > > diff --git a/xen/drivers/video/fb.c b/xen/drivers/video/fb.c > > new file mode 100644 > > index 0000000..282f97e > > --- /dev/null > > +++ b/xen/drivers/video/fb.c > > @@ -0,0 +1,209 @@ > > +/************************************************************************** > > **** > > + * fb.c > > + * > > + * linear frame buffer handling. > > + */ > > + > > +#include <xen/config.h> > > +#include <xen/kernel.h> > > +#include <xen/lib.h> > > +#include <xen/errno.h> > > +#include "fb.h" > > +#include "font.h" > > + > > +#define MAX_XRES 1900 > > +#define MAX_YRES 1200 > > +#define MAX_BPP 4 > > +#define MAX_FONT_W 8 > > +#define MAX_FONT_H 16 > > +static __initdata unsigned int line_len[MAX_XRES / MAX_FONT_W]; > > +static __initdata unsigned char lbuf[MAX_XRES * MAX_BPP]; > > +static __initdata unsigned char text_buf[(MAX_XRES / MAX_FONT_W) * \ > > + (MAX_YRES / MAX_FONT_H)]; > > + > > +struct fb_status { > > + struct fb_prop fbp; > > + > > + unsigned char *lbuf, *text_buf; > > + unsigned int *line_len; > > + unsigned int xpos, ypos; > > +}; > > +static struct fb_status fb; > > + > > +static void fb_show_line( > > + const unsigned char *text_line, > > + unsigned char *video_line, > > + unsigned int nr_chars, > > + unsigned int nr_cells) > > +{ > > + unsigned int i, j, b, bpp, pixel; > > + > > + bpp = (fb.fbp.bits_per_pixel + 7) >> 3; > > + > > + for ( i = 0; i < fb.fbp.font->height; i++ ) > > + { > > + unsigned char *ptr = fb.lbuf; > > + > > + for ( j = 0; j < nr_chars; j++ ) > > + { > > + const unsigned char *bits = fb.fbp.font->data; > > + bits += ((text_line[j] * fb.fbp.font->height + i) * > > + ((fb.fbp.font->width + 7) >> 3)); > > + for ( b = fb.fbp.font->width; b--; ) > > + { > > + pixel = (*bits & (1u<<b)) ? fb.fbp.pixel_on : 0; > > + memcpy(ptr, &pixel, bpp); > > + ptr += bpp; > > + } > > + } > > + > > + memset(ptr, 0, (fb.fbp.width - nr_chars * fb.fbp.font->width) * > > bpp); > > + memcpy(video_line, fb.lbuf, nr_cells * fb.fbp.font->width * bpp); > > + video_line += fb.fbp.bytes_per_line; > > + } > > +} > > + > > +/* Fast mode which redraws all modified parts of a 2D text buffer. */ > > +void fb_redraw_puts(const char *s) > > +{ > > + unsigned int i, min_redraw_y = fb.ypos; > > + char c; > > + > > + /* Paste characters into text buffer. */ > > + while ( (c = *s++) != '\0' ) > > + { > > + if ( (c == '\n') || (fb.xpos >= fb.fbp.text_columns) ) > > + { > > + if ( ++fb.ypos >= fb.fbp.text_rows ) > > + { > > + min_redraw_y = 0; > > + fb.ypos = fb.fbp.text_rows - 1; > > + memmove(fb.text_buf, fb.text_buf + fb.fbp.text_columns, > > + fb.ypos * fb.fbp.text_columns); > > + memset(fb.text_buf + fb.ypos * fb.fbp.text_columns, 0, > > fb.xpos); > > + } > > + fb.xpos = 0; > > + } > > + > > + if ( c != '\n' ) > > + fb.text_buf[fb.xpos++ + fb.ypos * fb.fbp.text_columns] = c; > > + } > > + > > + /* Render modified section of text buffer to VESA linear framebuffer. > > */ > > + for ( i = min_redraw_y; i <= fb.ypos; i++ ) > > + { > > + const unsigned char *line = fb.text_buf + i * fb.fbp.text_columns; > > + unsigned int width; > > + > > + for ( width = fb.fbp.text_columns; width; --width ) > > + if ( line[width - 1] ) > > + break; > > + fb_show_line(line, > > + fb.fbp.lfb + i * fb.fbp.font->height * > > fb.fbp.bytes_per_line, > > + width, max(fb.line_len[i], width)); > > + fb.line_len[i] = width; > > + } > > + > > + fb.fbp.flush(); > > +} > > + > > +/* Slower line-based scroll mode which interacts better with dom0. */ > > +void fb_scroll_puts(const char *s) > > +{ > > + unsigned int i; > > + char c; > > + > > + while ( (c = *s++) != '\0' ) > > + { > > + if ( (c == '\n') || (fb.xpos >= fb.fbp.text_columns) ) > > + { > > + unsigned int bytes = (fb.fbp.width * > > + ((fb.fbp.bits_per_pixel + 7) >> 3)); > > + unsigned char *src = fb.fbp.lfb + fb.fbp.font->height * > > fb.fbp.bytes_per_line; > > + unsigned char *dst = fb.fbp.lfb; > > + > > + /* New line: scroll all previous rows up one line. */ > > + for ( i = fb.fbp.font->height; i < fb.fbp.height; i++ ) > > + { > > + memcpy(dst, src, bytes); > > + src += fb.fbp.bytes_per_line; > > + dst += fb.fbp.bytes_per_line; > > + } > > + > > + /* Render new line. */ > > + fb_show_line( > > + fb.text_buf, > > + fb.fbp.lfb + (fb.fbp.text_rows-1) * fb.fbp.font->height * > > fb.fbp.bytes_per_line, > > + fb.xpos, fb.fbp.text_columns); > > + > > + fb.xpos = 0; > > + } > > + > > + if ( c != '\n' ) > > + fb.text_buf[fb.xpos++] = c; > > + } > > + > > + fb.fbp.flush(); > > +} > > + > > +void fb_cr(void) > > +{ > > + fb.xpos = 0; > > +} > > + > > +int __init fb_init(struct fb_prop fbp) > > +{ > > + if ( fbp.width > MAX_XRES || fbp.height > MAX_YRES ) > > + { > > + printk("Couldn't initialize a %xx%x framebuffer early.\n", > > + fbp.width, fbp.height); > > + return -EINVAL; > > + } > > + > > + fb.fbp = fbp; > > + fb.lbuf = lbuf; > > + fb.text_buf = text_buf; > > + fb.line_len = line_len; > > + return 0; > > +} > > + > > +int __init fb_alloc(void) > > +{ > > + fb.lbuf = NULL; > > + fb.text_buf = NULL; > > + fb.line_len = NULL; > > + > > + fb.lbuf = xmalloc_bytes(fb.fbp.bytes_per_line); > > + if ( !fb.lbuf ) > > + goto fail; > > + > > + fb.text_buf = xzalloc_bytes(fb.fbp.text_columns * fb.fbp.text_rows); > > + if ( !fb.text_buf ) > > + goto fail; > > + > > + fb.line_len = xzalloc_array(unsigned int, fb.fbp.text_columns); > > + if ( !fb.line_len ) > > + goto fail; > > + > > + memcpy(fb.lbuf, lbuf, fb.fbp.bytes_per_line); > > + memcpy(fb.text_buf, text_buf, fb.fbp.text_columns * fb.fbp.text_rows); > > + memcpy(fb.line_len, line_len, fb.fbp.text_columns); > > + > > + return 0; > > + > > +fail: > > + printk(XENLOG_ERR "Couldn't allocate enough memory to drive " > > + "the framebuffer\n"); > > + xfree(fb.lbuf); > > + xfree(fb.text_buf); > > + xfree(fb.line_len); > > + > > + return -ENOMEM; > > +} > > + > > +void fb_free(void) > > +{ > > + xfree(fb.lbuf); > > + xfree(fb.text_buf); > > + xfree(fb.line_len); > > +} > > diff --git a/xen/drivers/video/fb.h b/xen/drivers/video/fb.h > > new file mode 100644 > > index 0000000..558d058 > > --- /dev/null > > +++ b/xen/drivers/video/fb.h > > @@ -0,0 +1,49 @@ > > +/* > > + * xen/drivers/video/fb.h > > + * > > + * Cross-platform framebuffer library > > + * > > + * Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > > + * Copyright (c) 2012 Citrix Systems. > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License as published by > > + * the Free Software Foundation; either version 2 of the License, or > > + * (at your option) any later version. > > + * > > + * This program is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + * GNU General Public License for more details. > > + */ > > + > > +#ifndef _XEN_FB_H > > +#define _XEN_FB_H > > + > > +#include <xen/init.h> > > + > > +struct fb_prop { > > + const struct font_desc *font; > > + unsigned char *lfb; > > + unsigned int pixel_on; > > + uint16_t width, height; > > + uint16_t bytes_per_line; > > + uint16_t bits_per_pixel; > > + void (*flush)(void); > > + > > + unsigned int text_columns; > > + unsigned int text_rows; > > +}; > > + > > +void fb_redraw_puts(const char *s); > > +void fb_scroll_puts(const char *s); > > +void fb_cr(void); > > Please make this fb_create() or alike - "cr" alone could well be > mistaken as "carriage return". Actually it is supposed to be "cr": it is used by vesa_endboot to reset the cursor to column 0. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |