Hi all, these are the remaining unapplied patches of the ARM HDLCD patch series. Changes in v7: - rebased on b61ed421d2c85b5b106c63f2c14f8aa162b282f0; - turn more printk and panic into early_printk and early_panic. Changes in v6: - rebased on 77d3a1db3196b1b5864469f8d3f41d496800c795; - remove useless initializations to NULL in lfb_init; - more compact checks in lfb_init. Changes in v5: - move the barriers outside the loop in flush_xen_data_tlb_range_va; - move out of "introduce early_ioremap" any changes related to flush_xen_data_tlb_range_va and PAGE masks; - remove lfb_alloc and the now unused __initdata variables; - fix indentation and long lines; - reword commit message of "move setup_mm right after setup_pagetables"; - turn printk in setup_mm into an early_printk in setup_mm; - actually include the Makefile for xen/arch/arm/platforms. Changes in v4: - rename flush_xen_data_tlb_range to flush_xen_data_tlb_range_va; - replace all the calls to flush_xen_data_tlb_va, with calls to flush_xen_data_tlb_range_va; - flush the entire 2MB mapping at BOOT_MISC_VIRT_START rather than just the first 4k; - remove flush_xen_data_tlb_va; - fix indentation; - rename EARLY_VMAP_START/END to EARLY_VMAP_VIRT_START/END; - mark early_ioremap as __init; - reduce the amount of casts in early_ioremap; - squash the vesa.c changes into this patch; - rename fb* to lfb*; - pass a pointer to fb_init; - use %u for screen dimensions; - specify loglevel in printk; - call fb_free on error in fb_alloc; - no __init on declarations; - do not break messages to fit 80 columns; - remove "preserve DTB mappings"; - introduce a new "move setup_mm right after setup_pagetables" patch; - stop iterating over the DT nodes in device_tree_for_each_node if func returns a value != 0; - return 1 from _find_compatible_node when a node is found; - move the wait loop and the syscfg cfgctrl write into a separate function; - fix comments; - define all registers in write; - move platform_vexpress.c to platforms/vexpress.c; - move platform_vexpress.h to arm-arm/platforms/vexpress.h; - use a lookup table to set the color masks; - fix indentation; - make sure mode_string is not NULL and is not bigger than 16 chars before continuing; - introduce 2 separate error messages for !hdlcd_start and !framebuffer_start at the beginning of video_init; - mark get_color_masks and set_pixclock as __init; - check that we are running on a vexpress machine before calling vexpress_syscfg. Changes in v3: - rename fb_cr to fb_carriage_return. Changes in v2: - rebase on latest xen-unstable; - add support for multiple resolutions; - add support to dynamically change the OSC5 motherboard timer; - add the patch "preserve DTB mappings". Stefano Stabellini (5): xen: introduce a generic framebuffer driver xen/arm: move setup_mm right after setup_pagetables xen/device_tree: introduce find_compatible_node xen/arm: introduce vexpress_syscfg xen/arm: introduce a driver for the ARM HDLCD controller xen/arch/arm/Makefile | 1 + xen/arch/arm/Rules.mk | 1 + xen/arch/arm/arm32/mode_switch.S | 2 +- xen/arch/arm/platforms/Makefile | 1 + xen/arch/arm/platforms/vexpress.c | 100 +++++++++++ xen/arch/arm/setup.c | 14 +- xen/common/device_tree.c | 56 ++++++- xen/common/page_alloc.c | 6 - xen/drivers/video/Makefile | 2 + xen/drivers/video/arm_hdlcd.c | 276 ++++++++++++++++++++++++++++++ xen/drivers/video/lfb.c | 183 ++++++++++++++++++++ xen/drivers/video/lfb.h | 46 +++++ xen/drivers/video/modelines.h | 77 +++++++++ xen/drivers/video/vesa.c | 177 +++----------------- xen/include/asm-arm/config.h | 2 + xen/include/asm-arm/platform_vexpress.h | 17 -- xen/include/asm-arm/platforms/vexpress.h | 40 +++++ xen/include/xen/device_tree.h | 3 + 18 files changed, 817 insertions(+), 187 deletions(-) Cheers, Stefano
Stefano Stabellini
2013-Feb-14 17:30 UTC
[PATCH v7 1/5] xen: introduce a generic framebuffer driver
Abstract away from vesa.c the funcions to handle a linear framebuffer and print characters to it. Make use of the new functions in vesa.c. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Jan Beulich <JBeulich@suse.com> Changes in v6: - remove useless initializations to NULL in lfb_init; - more compact checks in lfb_init. Changes in v5: - remove lfb_alloc and the now unused __initdata variables; - fix indentation and long lines. Changes in v4: - squash the vesa.c changes into this patch; - rename fb* to lfb*; - pass a pointer to fb_init; - use %u for screen dimensions; - specify loglevel in printk; - call fb_free on error in fb_alloc; - no __init on declarations; - do not break messages to fit 80 columns. --- xen/drivers/video/Makefile | 1 + xen/drivers/video/lfb.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ xen/drivers/video/lfb.h | 46 +++++++++++ xen/drivers/video/vesa.c | 177 ++++++------------------------------------ 4 files changed, 254 insertions(+), 153 deletions(-) create mode 100644 xen/drivers/video/lfb.c create mode 100644 xen/drivers/video/lfb.h diff --git a/xen/drivers/video/Makefile b/xen/drivers/video/Makefile index 2993c39..77f9d5d 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) += lfb.o obj-$(HAS_VGA) += vesa.o diff --git a/xen/drivers/video/lfb.c b/xen/drivers/video/lfb.c new file mode 100644 index 0000000..cc7f7ac --- /dev/null +++ b/xen/drivers/video/lfb.c @@ -0,0 +1,183 @@ +/****************************************************************************** + * lfb.c + * + * linear frame buffer handling. + */ + +#include <xen/config.h> +#include <xen/kernel.h> +#include <xen/lib.h> +#include <xen/errno.h> +#include "lfb.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 + +struct lfb_status { + struct lfb_prop lfbp; + + unsigned char *lbuf, *text_buf; + unsigned int *line_len; + unsigned int xpos, ypos; +}; +static struct lfb_status lfb; + +static void lfb_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 = (lfb.lfbp.bits_per_pixel + 7) >> 3; + + for ( i = 0; i < lfb.lfbp.font->height; i++ ) + { + unsigned char *ptr = lfb.lbuf; + + for ( j = 0; j < nr_chars; j++ ) + { + const unsigned char *bits = lfb.lfbp.font->data; + bits += ((text_line[j] * lfb.lfbp.font->height + i) * + ((lfb.lfbp.font->width + 7) >> 3)); + for ( b = lfb.lfbp.font->width; b--; ) + { + pixel = (*bits & (1u<<b)) ? lfb.lfbp.pixel_on : 0; + memcpy(ptr, &pixel, bpp); + ptr += bpp; + } + } + + memset(ptr, 0, (lfb.lfbp.width - nr_chars * lfb.lfbp.font->width) * bpp); + memcpy(video_line, lfb.lbuf, nr_cells * lfb.lfbp.font->width * bpp); + video_line += lfb.lfbp.bytes_per_line; + } +} + +/* Fast mode which redraws all modified parts of a 2D text buffer. */ +void lfb_redraw_puts(const char *s) +{ + unsigned int i, min_redraw_y = lfb.ypos; + char c; + + /* Paste characters into text buffer. */ + while ( (c = *s++) != ''\0'' ) + { + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) + { + if ( ++lfb.ypos >= lfb.lfbp.text_rows ) + { + min_redraw_y = 0; + lfb.ypos = lfb.lfbp.text_rows - 1; + memmove(lfb.text_buf, lfb.text_buf + lfb.lfbp.text_columns, + lfb.ypos * lfb.lfbp.text_columns); + memset(lfb.text_buf + lfb.ypos * lfb.lfbp.text_columns, 0, lfb.xpos); + } + lfb.xpos = 0; + } + + if ( c != ''\n'' ) + lfb.text_buf[lfb.xpos++ + lfb.ypos * lfb.lfbp.text_columns] = c; + } + + /* Render modified section of text buffer to VESA linear framebuffer. */ + for ( i = min_redraw_y; i <= lfb.ypos; i++ ) + { + const unsigned char *line = lfb.text_buf + i * lfb.lfbp.text_columns; + unsigned int width; + + for ( width = lfb.lfbp.text_columns; width; --width ) + if ( line[width - 1] ) + break; + lfb_show_line(line, + lfb.lfbp.lfb + i * lfb.lfbp.font->height * lfb.lfbp.bytes_per_line, + width, max(lfb.line_len[i], width)); + lfb.line_len[i] = width; + } + + lfb.lfbp.flush(); +} + +/* Slower line-based scroll mode which interacts better with dom0. */ +void lfb_scroll_puts(const char *s) +{ + unsigned int i; + char c; + + while ( (c = *s++) != ''\0'' ) + { + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) + { + unsigned int bytes = (lfb.lfbp.width * + ((lfb.lfbp.bits_per_pixel + 7) >> 3)); + unsigned char *src = lfb.lfbp.lfb + lfb.lfbp.font->height * lfb.lfbp.bytes_per_line; + unsigned char *dst = lfb.lfbp.lfb; + + /* New line: scroll all previous rows up one line. */ + for ( i = lfb.lfbp.font->height; i < lfb.lfbp.height; i++ ) + { + memcpy(dst, src, bytes); + src += lfb.lfbp.bytes_per_line; + dst += lfb.lfbp.bytes_per_line; + } + + /* Render new line. */ + lfb_show_line( + lfb.text_buf, + lfb.lfbp.lfb + (lfb.lfbp.text_rows-1) * lfb.lfbp.font->height * + lfb.lfbp.bytes_per_line, + lfb.xpos, lfb.lfbp.text_columns); + + lfb.xpos = 0; + } + + if ( c != ''\n'' ) + lfb.text_buf[lfb.xpos++] = c; + } + + lfb.lfbp.flush(); +} + +void lfb_carriage_return(void) +{ + lfb.xpos = 0; +} + +int __init lfb_init(struct lfb_prop *lfbp) +{ + if ( lfbp->width > MAX_XRES || lfbp->height > MAX_YRES ) + { + printk(XENLOG_WARNING "Couldn''t initialize a %ux%u framebuffer early.\n", + lfbp->width, lfbp->height); + return -EINVAL; + } + + lfb.lfbp = *lfbp; + + lfb.lbuf = xmalloc_bytes(lfb.lfbp.bytes_per_line); + lfb.text_buf = xzalloc_bytes(lfb.lfbp.text_columns * lfb.lfbp.text_rows); + lfb.line_len = xzalloc_array(unsigned int, lfb.lfbp.text_columns); + + if ( !lfb.lbuf || !lfb.text_buf || !lfb.line_len ) + goto fail; + + return 0; + +fail: + printk(XENLOG_ERR "Couldn''t allocate enough memory to drive the framebuffer\n"); + lfb_free(); + + return -ENOMEM; +} + +void lfb_free(void) +{ + xfree(lfb.lbuf); + xfree(lfb.text_buf); + xfree(lfb.line_len); +} diff --git a/xen/drivers/video/lfb.h b/xen/drivers/video/lfb.h new file mode 100644 index 0000000..ac40a66 --- /dev/null +++ b/xen/drivers/video/lfb.h @@ -0,0 +1,46 @@ +/* + * xen/drivers/video/lfb.h + * + * Cross-platform framebuffer library + * + * Stefano Stabellini <stefano.stabellini@eu.citrix.com> + * Copyright (c) 2013 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_LFB_H +#define _XEN_LFB_H + +#include <xen/init.h> + +struct lfb_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 lfb_redraw_puts(const char *s); +void lfb_scroll_puts(const char *s); +void lfb_carriage_return(void); +void lfb_free(void); + +/* initialize the framebuffer */ +int lfb_init(struct lfb_prop *lfbp); + +#endif diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c index aaf8b23..1144f76 100644 --- a/xen/drivers/video/vesa.c +++ b/xen/drivers/video/vesa.c @@ -13,20 +13,15 @@ #include <asm/io.h> #include <asm/page.h> #include "font.h" +#include "lfb.h" #define vlfb_info vga_console_info.u.vesa_lfb -#define text_columns (vlfb_info.width / font->width) -#define text_rows (vlfb_info.height / font->height) -static void vesa_redraw_puts(const char *s); -static void vesa_scroll_puts(const char *s); +static void lfb_flush(void); -static unsigned char *lfb, *lbuf, *text_buf; -static unsigned int *__initdata line_len; +static unsigned char *lfb; static const struct font_desc *font; static bool_t vga_compat; -static unsigned int pixel_on; -static unsigned int xpos, ypos; static unsigned int vram_total; integer_param("vesa-ram", vram_total); @@ -87,29 +82,26 @@ void __init vesa_early_init(void) void __init vesa_init(void) { - if ( !font ) - goto fail; - - lbuf = xmalloc_bytes(vlfb_info.bytes_per_line); - if ( !lbuf ) - goto fail; + struct lfb_prop lfbp; - text_buf = xzalloc_bytes(text_columns * text_rows); - if ( !text_buf ) - goto fail; + if ( !font ) + return; - line_len = xzalloc_array(unsigned int, text_columns); - if ( !line_len ) - goto fail; + lfbp.font = font; + lfbp.bits_per_pixel = vlfb_info.bits_per_pixel; + lfbp.bytes_per_line = vlfb_info.bytes_per_line; + lfbp.width = vlfb_info.width; + lfbp.height = vlfb_info.height; + lfbp.flush = lfb_flush; + lfbp.text_columns = vlfb_info.width / font->width; + lfbp.text_rows = vlfb_info.height / font->height; - lfb = ioremap(vlfb_info.lfb_base, vram_remap); + lfbp.lfb = lfb = ioremap(vlfb_info.lfb_base, vram_remap); if ( !lfb ) - goto fail; + return; memset(lfb, 0, vram_remap); - video_puts = vesa_redraw_puts; - printk(XENLOG_INFO "vesafb: framebuffer at %#x, mapped to 0x%p, " "using %uk, total %uk\n", vlfb_info.lfb_base, lfb, @@ -131,7 +123,7 @@ void __init vesa_init(void) { /* Light grey in truecolor. */ unsigned int grey = 0xaaaaaaaa; - pixel_on = + fbp.pixel_on = ((grey >> (32 - vlfb_info. red_size)) << vlfb_info. red_pos) | ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) | ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos); @@ -139,15 +131,12 @@ void __init vesa_init(void) else { /* White(ish) in default pseudocolor palette. */ - pixel_on = 7; + fbp.pixel_on = 7; } - return; - - fail: - xfree(lbuf); - xfree(text_buf); - xfree(line_len); + if ( lfb_init(&lfbp) < 0 ) + return; + video_puts = lfb_redraw_puts; } #include <asm/mtrr.h> @@ -192,8 +181,8 @@ void __init vesa_endboot(bool_t keep) { if ( keep ) { - xpos = 0; - video_puts = vesa_scroll_puts; + video_puts = lfb_scroll_puts; + lfb_carriage_return(); } else { @@ -202,124 +191,6 @@ void __init vesa_endboot(bool_t keep) memset(lfb + i * vlfb_info.bytes_per_line, 0, vlfb_info.width * bpp); lfb_flush(); + lfb_free(); } - - xfree(line_len); -} - -/* Render one line of text to given linear framebuffer line. */ -static void vesa_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 = (vlfb_info.bits_per_pixel + 7) >> 3; - - for ( i = 0; i < font->height; i++ ) - { - unsigned char *ptr = lbuf; - - for ( j = 0; j < nr_chars; j++ ) - { - const unsigned char *bits = font->data; - bits += ((text_line[j] * font->height + i) * - ((font->width + 7) >> 3)); - for ( b = font->width; b--; ) - { - pixel = (*bits & (1u<<b)) ? pixel_on : 0; - memcpy(ptr, &pixel, bpp); - ptr += bpp; - } - } - - memset(ptr, 0, (vlfb_info.width - nr_chars * font->width) * bpp); - memcpy(video_line, lbuf, nr_cells * font->width * bpp); - video_line += vlfb_info.bytes_per_line; - } -} - -/* Fast mode which redraws all modified parts of a 2D text buffer. */ -static void __init vesa_redraw_puts(const char *s) -{ - unsigned int i, min_redraw_y = ypos; - char c; - - /* Paste characters into text buffer. */ - while ( (c = *s++) != ''\0'' ) - { - if ( (c == ''\n'') || (xpos >= text_columns) ) - { - if ( ++ypos >= text_rows ) - { - min_redraw_y = 0; - ypos = text_rows - 1; - memmove(text_buf, text_buf + text_columns, - ypos * text_columns); - memset(text_buf + ypos * text_columns, 0, xpos); - } - xpos = 0; - } - - if ( c != ''\n'' ) - text_buf[xpos++ + ypos * text_columns] = c; - } - - /* Render modified section of text buffer to VESA linear framebuffer. */ - for ( i = min_redraw_y; i <= ypos; i++ ) - { - const unsigned char *line = text_buf + i * text_columns; - unsigned int width; - - for ( width = text_columns; width; --width ) - if ( line[width - 1] ) - break; - vesa_show_line(line, - lfb + i * font->height * vlfb_info.bytes_per_line, - width, max(line_len[i], width)); - line_len[i] = width; - } - - lfb_flush(); -} - -/* Slower line-based scroll mode which interacts better with dom0. */ -static void vesa_scroll_puts(const char *s) -{ - unsigned int i; - char c; - - while ( (c = *s++) != ''\0'' ) - { - if ( (c == ''\n'') || (xpos >= text_columns) ) - { - unsigned int bytes = (vlfb_info.width * - ((vlfb_info.bits_per_pixel + 7) >> 3)); - unsigned char *src = lfb + font->height * vlfb_info.bytes_per_line; - unsigned char *dst = lfb; - - /* New line: scroll all previous rows up one line. */ - for ( i = font->height; i < vlfb_info.height; i++ ) - { - memcpy(dst, src, bytes); - src += vlfb_info.bytes_per_line; - dst += vlfb_info.bytes_per_line; - } - - /* Render new line. */ - vesa_show_line( - text_buf, - lfb + (text_rows-1) * font->height * vlfb_info.bytes_per_line, - xpos, text_columns); - - xpos = 0; - } - - if ( c != ''\n'' ) - text_buf[xpos++] = c; - } - - lfb_flush(); } -- 1.7.2.5
Stefano Stabellini
2013-Feb-14 17:30 UTC
[PATCH v7 2/5] xen/arm: move setup_mm right after setup_pagetables
At the moment we destroy the DTB mappings we have in setup_pagetables and we restore them only in setup_mm. Move setup_mm right after setup_pagetables. This ensures we have a valid DTB mapping while running the subsequent initialization code. Changes in v7: - turn more printk''s into early_printk. Changes in v5: - reword commit message; - turn printk in setup_mm into an early_printk. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- xen/arch/arm/setup.c | 7 +++---- xen/common/page_alloc.c | 6 ------ 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index e1ab7f6..c568be5 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -246,11 +246,11 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) } while ( xenheap_pages > 128<<(20-PAGE_SHIFT) ); if ( ! e ) - panic("Not not enough space for xenheap\n"); + early_panic("Not not enough space for xenheap\n"); domheap_pages = heap_pages - xenheap_pages; - printk("Xen heap: %lu pages Dom heap: %lu pages\n", xenheap_pages, domheap_pages); + early_printk("Xen heap: %lu pages Dom heap: %lu pages\n", xenheap_pages, domheap_pages); setup_xenheap_mappings((e >> PAGE_SHIFT) - xenheap_pages, xenheap_pages); @@ -349,6 +349,7 @@ void __init start_xen(unsigned long boot_phys_offset, cmdline_parse(device_tree_bootargs(fdt)); setup_pagetables(boot_phys_offset, get_xen_paddr()); + setup_mm(atag_paddr, fdt_size); #ifdef EARLY_UART_ADDRESS /* TODO Need to get device tree or command line for UART address */ @@ -366,8 +367,6 @@ void __init start_xen(unsigned long boot_phys_offset, set_current((struct vcpu *)0xfffff000); /* debug sanity */ idle_vcpu[0] = current; - setup_mm(atag_paddr, fdt_size); - /* Setup Hyp vector base */ WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR); printk("Set hyp vector base to %"PRIx32" (expected %p)\n", diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 6b8bc39..6c2215b 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -182,12 +182,6 @@ void __init init_boot_pages(paddr_t ps, paddr_t pe) else if ( *p != ''\0'' ) break; - if ( bad_epfn == bad_spfn ) - printk("Marking page %lx as bad\n", bad_spfn); - else - printk("Marking pages %lx through %lx as bad\n", - bad_spfn, bad_epfn); - bootmem_region_zap(bad_spfn, bad_epfn+1); } } -- 1.7.2.5
Stefano Stabellini
2013-Feb-14 17:30 UTC
[PATCH v7 3/5] xen/device_tree: introduce find_compatible_node
Introduce a find_compatible_node function that can be used by device drivers to find the node corresponding to their device in the device tree. Initialize device_tree_flattened early in start_xen, so that it is available before setup_mm. Get rid of fdt in the process. Also add device_tree_node_compatible to device_tree.h, that is currently missing. Changes in v4: - stop iterating over the DT nodes in device_tree_for_each_node if func returns a value != 0; - return 1 from _find_compatible_node when a node is found. Changes in v2: - remove fdt; - return early from _find_compatible_node, if a node has already been found. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- xen/arch/arm/setup.c | 7 ++--- xen/common/device_tree.c | 56 +++++++++++++++++++++++++++++++++++++++- xen/include/xen/device_tree.h | 3 ++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index c568be5..52d2e7a 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -333,7 +333,6 @@ void __init start_xen(unsigned long boot_phys_offset, unsigned long atag_paddr, unsigned long cpuid) { - void *fdt; size_t fdt_size; int cpus, i; @@ -341,12 +340,12 @@ void __init start_xen(unsigned long boot_phys_offset, smp_clear_cpu_maps(); - fdt = (void *)BOOT_MISC_VIRT_START + device_tree_flattened = (void *)BOOT_MISC_VIRT_START + (atag_paddr & ((1 << SECOND_SHIFT) - 1)); - fdt_size = device_tree_early_init(fdt); + fdt_size = device_tree_early_init(device_tree_flattened); cpus = smp_get_max_cpus(); - cmdline_parse(device_tree_bootargs(fdt)); + cmdline_parse(device_tree_bootargs(device_tree_flattened)); setup_pagetables(boot_phys_offset, get_xen_paddr()); setup_mm(atag_paddr, fdt_size); diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 260c2d4..cef4b88 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -140,7 +140,7 @@ u32 device_tree_get_u32(const void *fdt, int node, const char *prop_name) * Any nodes nested at DEVICE_TREE_MAX_DEPTH or deeper are ignored. * * Returns 0 if all nodes were iterated over successfully. If @func - * returns a negative value, that value is returned immediately. + * returns a value different from 0, that value is returned immediately. */ int device_tree_for_each_node(const void *fdt, device_tree_node_func func, void *data) @@ -169,12 +169,64 @@ int device_tree_for_each_node(const void *fdt, ret = func(fdt, node, name, depth, address_cells[depth-1], size_cells[depth-1], data); - if ( ret < 0 ) + if ( ret != 0 ) return ret; } return 0; } +struct find_compat { + const char *compatible; + int found; + int node; + int depth; + u32 address_cells; + u32 size_cells; +}; + +static int _find_compatible_node(const void *fdt, + int node, const char *name, int depth, + u32 address_cells, u32 size_cells, + void *data) +{ + struct find_compat *c = (struct find_compat *) data; + + if ( c->found ) + return 1; + + if ( device_tree_node_compatible(fdt, node, c->compatible) ) + { + c->found = 1; + c->node = node; + c->depth = depth; + c->address_cells = address_cells; + c->size_cells = size_cells; + return 1; + } + return 0; +} + +int find_compatible_node(const char *compatible, int *node, int *depth, + u32 *address_cells, u32 *size_cells) +{ + int ret; + struct find_compat c; + c.compatible = compatible; + c.found = 0; + + ret = device_tree_for_each_node(device_tree_flattened, _find_compatible_node, &c); + if ( !c.found ) + return ret; + else + { + *node = c.node; + *depth = c.depth; + *address_cells = c.address_cells; + *size_cells = c.size_cells; + return 1; + } +} + /** * device_tree_bootargs - return the bootargs (the Xen command line) * @fdt flat device tree. diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h index 52ef258..1d04e4f 100644 --- a/xen/include/xen/device_tree.h +++ b/xen/include/xen/device_tree.h @@ -68,6 +68,9 @@ void device_tree_set_reg(u32 **cell, u32 address_cells, u32 size_cells, u64 start, u64 size); u32 device_tree_get_u32(const void *fdt, int node, const char *prop_name); bool_t device_tree_node_matches(const void *fdt, int node, const char *match); +bool_t device_tree_node_compatible(const void *fdt, int node, const char *match); +int find_compatible_node(const char *compatible, int *node, int *depth, + u32 *address_cells, u32 *size_cells); int device_tree_for_each_node(const void *fdt, device_tree_node_func func, void *data); const char *device_tree_bootargs(const void *fdt); -- 1.7.2.5
Stefano Stabellini
2013-Feb-14 17:30 UTC
[PATCH v7 4/5] xen/arm: introduce vexpress_syscfg
Introduce a Versatile Express specific function to read/write motherboard settings. Changes in v5: - actually include the Makefile. Changes in v4: - move the wait loop and the syscfg cfgctrl write into a separate function; - fix comments; - define all registers in write; - move platform_vexpress.c to platforms/vexpress.c; - move platform_vexpress.h to arm-arm/platforms/vexpress.h. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- xen/arch/arm/Makefile | 1 + xen/arch/arm/arm32/mode_switch.S | 2 +- xen/arch/arm/platforms/Makefile | 1 + xen/arch/arm/platforms/vexpress.c | 100 ++++++++++++++++++++++++++++++ xen/include/asm-arm/platform_vexpress.h | 17 ----- xen/include/asm-arm/platforms/vexpress.h | 40 ++++++++++++ 6 files changed, 143 insertions(+), 18 deletions(-) create mode 100644 xen/arch/arm/platforms/Makefile create mode 100644 xen/arch/arm/platforms/vexpress.c delete mode 100644 xen/include/asm-arm/platform_vexpress.h create mode 100644 xen/include/asm-arm/platforms/vexpress.h diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index f2822f2..3954dbb 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -1,4 +1,5 @@ subdir-$(arm32) += arm32 +subdir-y += platforms obj-y += early_printk.o obj-y += domain.o diff --git a/xen/arch/arm/arm32/mode_switch.S b/xen/arch/arm/arm32/mode_switch.S index 411eb92..bc2be74 100644 --- a/xen/arch/arm/arm32/mode_switch.S +++ b/xen/arch/arm/arm32/mode_switch.S @@ -19,7 +19,7 @@ #include <asm/config.h> #include <asm/page.h> -#include <asm/platform_vexpress.h> +#include <asm/platforms/vexpress.h> #include <asm/asm_defns.h> #include <asm/gic.h> diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile new file mode 100644 index 0000000..4313e95 --- /dev/null +++ b/xen/arch/arm/platforms/Makefile @@ -0,0 +1 @@ +obj-y += vexpress.o diff --git a/xen/arch/arm/platforms/vexpress.c b/xen/arch/arm/platforms/vexpress.c new file mode 100644 index 0000000..b57b62e --- /dev/null +++ b/xen/arch/arm/platforms/vexpress.c @@ -0,0 +1,100 @@ +/* + * xen/arch/arm/platform_vexpress.c + * + * Versatile Express specific settings + * + * Stefano Stabellini <stefano.stabellini@eu.citrix.com> + * Copyright (c) 2013 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. + */ + +#include <asm/platforms/vexpress.h> +#include <xen/mm.h> + +#define DCC_SHIFT 26 +#define FUNCTION_SHIFT 20 +#define SITE_SHIFT 16 +#define POSITION_SHIFT 12 +#define DEVICE_SHIFT 0 + +static inline int vexpress_ctrl_start(uint32_t *syscfg, int write, + int function, int device) +{ + int dcc = 0; /* DCC to access */ + int site = 0; /* motherboard */ + int position = 0; /* daughterboard */ + uint32_t stat; + + /* set control register */ + syscfg[V2M_SYS_CFGCTRL/4] = V2M_SYS_CFG_START | + (write ? V2M_SYS_CFG_WRITE : 0) | + (dcc << DCC_SHIFT) | (function << FUNCTION_SHIFT) | + (site << SITE_SHIFT) | (position << POSITION_SHIFT) | + (device << DEVICE_SHIFT); + + /* wait for complete flag to be set */ + do { + stat = syscfg[V2M_SYS_CFGSTAT/4]; + dsb(); + } while ( !(stat & V2M_SYS_CFG_COMPLETE) ); + + /* check error status and return error flag if set */ + if ( stat & V2M_SYS_CFG_ERROR ) + { + printk(KERN_ERR "V2M SYS_CFGSTAT reported a configuration error\n"); + return -1; + } + return 0; +} + +int vexpress_syscfg(int write, int function, int device, uint32_t *data) +{ + uint32_t *syscfg = (uint32_t *) FIXMAP_ADDR(FIXMAP_MISC); + int ret = -1; + + set_fixmap(FIXMAP_MISC, V2M_SYS_MMIO_BASE >> PAGE_SHIFT, DEV_SHARED); + + if ( syscfg[V2M_SYS_CFGCTRL/4] & V2M_SYS_CFG_START ) + goto out; + + /* clear the complete bit in the V2M_SYS_CFGSTAT status register */ + syscfg[V2M_SYS_CFGSTAT/4] = 0; + + if ( write ) + { + /* write data */ + syscfg[V2M_SYS_CFGDATA/4] = *data; + + if ( vexpress_ctrl_start(syscfg, write, function, device) < 0 ) + goto out; + } else { + if ( vexpress_ctrl_start(syscfg, write, function, device) < 0 ) + goto out; + else + /* read data */ + *data = syscfg[V2M_SYS_CFGDATA/4]; + } + + ret = 0; +out: + clear_fixmap(FIXMAP_MISC); + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/platform_vexpress.h b/xen/include/asm-arm/platform_vexpress.h deleted file mode 100644 index 3556af3..0000000 --- a/xen/include/asm-arm/platform_vexpress.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __ASM_ARM_PLATFORM_H -#define __ASM_ARM_PLATFORM_H - -/* V2M */ -#define V2M_SYS_MMIO_BASE (0x1c010000) -#define V2M_SYS_FLAGSSET (0x30) -#define V2M_SYS_FLAGSCLR (0x34) - -#endif /* __ASM_ARM_PLATFORM_H */ -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/asm-arm/platforms/vexpress.h b/xen/include/asm-arm/platforms/vexpress.h new file mode 100644 index 0000000..e464913 --- /dev/null +++ b/xen/include/asm-arm/platforms/vexpress.h @@ -0,0 +1,40 @@ +#ifndef __ASM_ARM_PLATFORMS_VEXPRESS_H +#define __ASM_ARM_PLATFORMS_VEXPRESS_H + +/* V2M */ +#define V2M_SYS_MMIO_BASE (0x1c010000) +#define V2M_SYS_FLAGSSET (0x30) +#define V2M_SYS_FLAGSCLR (0x34) + +#define V2M_SYS_CFGDATA (0x00A0) +#define V2M_SYS_CFGCTRL (0x00A4) +#define V2M_SYS_CFGSTAT (0x00A8) + +#define V2M_SYS_CFG_START (1<<31) +#define V2M_SYS_CFG_WRITE (1<<30) +#define V2M_SYS_CFG_ERROR (1<<1) +#define V2M_SYS_CFG_COMPLETE (1<<0) + +#define V2M_SYS_CFG_OSC_FUNC 1 +#define V2M_SYS_CFG_OSC0 0 +#define V2M_SYS_CFG_OSC1 1 +#define V2M_SYS_CFG_OSC2 2 +#define V2M_SYS_CFG_OSC3 3 +#define V2M_SYS_CFG_OSC4 4 +#define V2M_SYS_CFG_OSC5 5 + +#ifndef __ASSEMBLY__ +#include <xen/inttypes.h> + +int vexpress_syscfg(int write, int function, int device, uint32_t *data); +#endif + +#endif /* __ASM_ARM_PLATFORMS_VEXPRESS_H */ +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.7.2.5
Stefano Stabellini
2013-Feb-14 17:30 UTC
[PATCH v7 5/5] xen/arm: introduce a driver for the ARM HDLCD controller
Read the screen resolution setting from device tree, find the corresponding modeline in a small table of standard video modes, set the hardware accordingly. Use vexpress_syscfg to configure the pixel clock. Use the generic framebuffer functions to print on the screen. Changes in v4: - use a lookup table to set the color masks; - fix indentation; - make sure mode_string is not NULL and is not bigger than 16 chars before continuing; - introduce 2 separate error messages for !hdlcd_start and !framebuffer_start at the beginning of video_init; - mark get_color_masks and set_pixclock as __init; - check that we are running on a vexpress machine before calling vexpress_syscfg. Changes in v2: - read mode from DT; - support multiple resolutions; - use vexpress_syscfg to set the pixclock. Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> --- xen/arch/arm/Rules.mk | 1 + xen/drivers/video/Makefile | 1 + xen/drivers/video/arm_hdlcd.c | 276 +++++++++++++++++++++++++++++++++++++++++ xen/drivers/video/modelines.h | 77 ++++++++++++ xen/include/asm-arm/config.h | 2 + 5 files changed, 357 insertions(+), 0 deletions(-) create mode 100644 xen/drivers/video/arm_hdlcd.c create mode 100644 xen/drivers/video/modelines.h diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk index 5b5768a..0843e50 100644 --- a/xen/arch/arm/Rules.mk +++ b/xen/arch/arm/Rules.mk @@ -8,6 +8,7 @@ HAS_DEVICE_TREE := y HAS_VIDEO := y +HAS_ARM_HDLCD := y CFLAGS += -fno-builtin -fno-common -Wredundant-decls CFLAGS += -iwithprefix include -Werror -Wno-pointer-arith -pipe diff --git a/xen/drivers/video/Makefile b/xen/drivers/video/Makefile index 77f9d5d..a756292 100644 --- a/xen/drivers/video/Makefile +++ b/xen/drivers/video/Makefile @@ -4,3 +4,4 @@ obj-$(HAS_VIDEO) += font_8x16.o obj-$(HAS_VIDEO) += font_8x8.o obj-$(HAS_VIDEO) += lfb.o obj-$(HAS_VGA) += vesa.o +obj-$(HAS_ARM_HDLCD) += arm_hdlcd.o diff --git a/xen/drivers/video/arm_hdlcd.c b/xen/drivers/video/arm_hdlcd.c new file mode 100644 index 0000000..45f9d64 --- /dev/null +++ b/xen/drivers/video/arm_hdlcd.c @@ -0,0 +1,276 @@ +/* + * xen/drivers/video/arm_hdlcd.c + * + * Driver for ARM HDLCD Controller + * + * Stefano Stabellini <stefano.stabellini@eu.citrix.com> + * Copyright (c) 2013 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. + */ + +#include <asm/delay.h> +#include <asm/types.h> +#include <asm/platforms/vexpress.h> +#include <xen/config.h> +#include <xen/device_tree.h> +#include <xen/libfdt/libfdt.h> +#include <xen/init.h> +#include <xen/mm.h> +#include "font.h" +#include "lfb.h" +#include "modelines.h" + +#define HDLCD ((volatile uint32_t *) FIXMAP_ADDR(FIXMAP_MISC)) + +#define HDLCD_INTMASK (0x18/4) +#define HDLCD_FBBASE (0x100/4) +#define HDLCD_LINELENGTH (0x104/4) +#define HDLCD_LINECOUNT (0x108/4) +#define HDLCD_LINEPITCH (0x10C/4) +#define HDLCD_BUS (0x110/4) +#define HDLCD_VSYNC (0x200/4) +#define HDLCD_VBACK (0x204/4) +#define HDLCD_VDATA (0x208/4) +#define HDLCD_VFRONT (0x20C/4) +#define HDLCD_HSYNC (0x210/4) +#define HDLCD_HBACK (0x214/4) +#define HDLCD_HDATA (0x218/4) +#define HDLCD_HFRONT (0x21C/4) +#define HDLCD_POLARITIES (0x220/4) +#define HDLCD_COMMAND (0x230/4) +#define HDLCD_PF (0x240/4) +#define HDLCD_RED (0x244/4) +#define HDLCD_GREEN (0x248/4) +#define HDLCD_BLUE (0x24C/4) + +struct color_masks { + int red_shift; + int red_size; + int green_shift; + int green_size; + int blue_shift; + int blue_size; +}; + +struct pixel_colors { + const char* bpp; + struct color_masks colors; +}; + +struct pixel_colors __initdata colors[] = { + { "16", { 0, 5, 11, 5, 6, 5 } }, + { "24", { 0, 8, 16, 8, 8, 8 } }, + { "32", { 0, 8, 16, 8, 8, 8 } }, +}; + +static void vga_noop_puts(const char *s) {} +void (*video_puts)(const char *) = vga_noop_puts; + +static void hdlcd_flush(void) +{ + dsb(); +} + +static int __init get_color_masks(const char* bpp, struct color_masks **masks) +{ + int i; + for ( i = 0; i < ARRAY_SIZE(colors); i++ ) + { + if ( !strncmp(colors[i].bpp, bpp, 2) ) + { + *masks = &colors[i].colors; + return 0; + } + } + return -1; +} + +static void __init set_pixclock(uint32_t pixclock) +{ + if ( device_tree_node_compatible(device_tree_flattened, 0, "arm,vexpress") ) + vexpress_syscfg(1, V2M_SYS_CFG_OSC_FUNC, + V2M_SYS_CFG_OSC5, &pixclock); +} + +void __init video_init(void) +{ + int node, depth; + u32 address_cells, size_cells; + struct lfb_prop lfbp; + unsigned char *lfb; + paddr_t hdlcd_start, hdlcd_size; + paddr_t framebuffer_start, framebuffer_size; + const struct fdt_property *prop; + const u32 *cell; + const char *mode_string; + char _mode_string[16]; + int bytes_per_pixel = 4; + struct color_masks *c = NULL; + struct modeline *videomode = NULL; + int i; + + if ( find_compatible_node("arm,hdlcd", &node, &depth, + &address_cells, &size_cells) <= 0 ) + return; + + prop = fdt_get_property(device_tree_flattened, node, "reg", NULL); + if ( !prop ) + return; + + cell = (const u32 *)prop->data; + device_tree_get_reg(&cell, address_cells, size_cells, + &hdlcd_start, &hdlcd_size); + + prop = fdt_get_property(device_tree_flattened, node, "framebuffer", NULL); + if ( !prop ) + return; + + cell = (const u32 *)prop->data; + device_tree_get_reg(&cell, address_cells, size_cells, + &framebuffer_start, &framebuffer_size); + + if ( !hdlcd_start ) + { + printk(KERN_ERR "HDLCD address missing from device tree, disabling driver\n"); + return; + } + + if ( !hdlcd_start || !framebuffer_start ) + { + printk(KERN_ERR "HDLCD: framebuffer address missing from device tree, disabling driver\n"); + return; + } + + mode_string = fdt_getprop(device_tree_flattened, node, "mode", NULL); + if ( !mode_string ) + { + get_color_masks("32", &c); + memcpy(_mode_string, "1280x1024@60", strlen("1280x1024@60") + 1); + bytes_per_pixel = 4; + } + else if ( strlen(mode_string) < strlen("800x600@60") || + strlen(mode_string) > sizeof(_mode_string) - 1 ) + { + printk(KERN_ERR "HDLCD: invalid modeline=%s\n", mode_string); + return; + } else { + char *s = strchr(mode_string, ''-''); + if ( !s ) + { + printk(KERN_INFO "HDLCD: bpp not found in modeline %s, assume 32 bpp\n", + mode_string); + get_color_masks("32", &c); + memcpy(_mode_string, mode_string, strlen(mode_string) + 1); + bytes_per_pixel = 4; + } else { + if ( strlen(s) < 6 ) + { + printk(KERN_ERR "HDLCD: invalid mode %s\n", mode_string); + return; + } + s++; + if ( get_color_masks(s, &c) < 0 ) + { + printk(KERN_WARNING "HDLCD: unsupported bpp %s\n", s); + return; + } + bytes_per_pixel = simple_strtoll(s, NULL, 10) / 8; + } + i = s - mode_string - 1; + memcpy(_mode_string, mode_string, i); + memcpy(_mode_string + i, mode_string + i + 3, 4); + } + + for ( i = 0; i < ARRAY_SIZE(videomodes); i++ ) { + if ( !strcmp(_mode_string, videomodes[i].mode) ) + { + videomode = &videomodes[i]; + break; + } + } + if ( !videomode ) + { + printk(KERN_WARNING "HDLCD: unsupported videomode %s\n", _mode_string); + return; + } + + if ( framebuffer_size < bytes_per_pixel * videomode->xres * videomode->yres ) + { + printk(KERN_ERR "HDLCD: the framebuffer is too small, disabling the HDLCD driver\n"); + return; + } + + printk(KERN_INFO "Initializing HDLCD driver\n"); + + lfb = early_ioremap(framebuffer_start, framebuffer_size, DEV_WC); + if ( !lfb ) + { + printk(KERN_ERR "Couldn''t map the framebuffer\n"); + return; + } + memset(lfb, 0x00, bytes_per_pixel * videomode->xres * videomode->yres); + + /* uses FIXMAP_MISC */ + set_pixclock(videomode->pixclock); + + set_fixmap(FIXMAP_MISC, hdlcd_start >> PAGE_SHIFT, DEV_SHARED); + HDLCD[HDLCD_COMMAND] = 0; + + HDLCD[HDLCD_LINELENGTH] = videomode->xres * bytes_per_pixel; + HDLCD[HDLCD_LINECOUNT] = videomode->yres - 1; + HDLCD[HDLCD_LINEPITCH] = videomode->xres * bytes_per_pixel; + HDLCD[HDLCD_PF] = ((bytes_per_pixel - 1) << 3); + HDLCD[HDLCD_INTMASK] = 0; + HDLCD[HDLCD_FBBASE] = framebuffer_start; + HDLCD[HDLCD_BUS] = 0xf00 | (1 << 4); + HDLCD[HDLCD_VBACK] = videomode->vback - 1; + HDLCD[HDLCD_VSYNC] = videomode->vsync - 1; + HDLCD[HDLCD_VDATA] = videomode->yres - 1; + HDLCD[HDLCD_VFRONT] = videomode->vfront - 1; + HDLCD[HDLCD_HBACK] = videomode->hback - 1; + HDLCD[HDLCD_HSYNC] = videomode->hsync - 1; + HDLCD[HDLCD_HDATA] = videomode->xres - 1; + HDLCD[HDLCD_HFRONT] = videomode->hfront - 1; + HDLCD[HDLCD_POLARITIES] = (1 << 2) | (1 << 3); + HDLCD[HDLCD_RED] = (c->red_size << 8) | c->red_shift; + HDLCD[HDLCD_GREEN] = (c->green_size << 8) | c->green_shift; + HDLCD[HDLCD_BLUE] = (c->blue_size << 8) | c->blue_shift; + HDLCD[HDLCD_COMMAND] = 1; + clear_fixmap(FIXMAP_MISC); + + lfbp.pixel_on = (((1 << c->red_size) - 1) << c->red_shift) | + (((1 << c->green_size) - 1) << c->green_shift) | + (((1 << c->blue_size) - 1) << c->blue_shift); + lfbp.lfb = lfb; + lfbp.font = &font_vga_8x16; + lfbp.bits_per_pixel = bytes_per_pixel*8; + lfbp.bytes_per_line = bytes_per_pixel*videomode->xres; + lfbp.width = videomode->xres; + lfbp.height = videomode->yres; + lfbp.flush = hdlcd_flush; + lfbp.text_columns = videomode->xres / 8; + lfbp.text_rows = videomode->yres / 16; + if ( lfb_init(&lfbp) < 0 ) + return; + video_puts = lfb_scroll_puts; +} + +void __init video_endboot(void) { } + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/drivers/video/modelines.h b/xen/drivers/video/modelines.h new file mode 100644 index 0000000..9cb7cdd --- /dev/null +++ b/xen/drivers/video/modelines.h @@ -0,0 +1,77 @@ +/* + * xen/drivers/video/modelines.h + * + * Timings for many popular monitor resolutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 1999 by The XFree86 Project, Inc. + * Copyright (c) 2013 Citrix Systems + */ + +#ifndef _XEN_MODLINES_H +#define _XEN_MODLINES_H + +struct modeline { + const char* mode; /* in the form 1280x1024@60 */ + uint32_t pixclock; /* Khz */ + uint32_t xres; + uint32_t hfront; /* horizontal front porch in pixels */ + uint32_t hsync; /* horizontal sync pulse in pixels */ + uint32_t hback; /* horizontal back porch in pixels */ + uint32_t yres; + uint32_t vfront; /* vertical front porch in lines */ + uint32_t vsync; /* vertical sync pulse in lines */ + uint32_t vback; /* vertical back porch in lines */ +}; + +struct modeline __initdata videomodes[] = { + { "640x480@60", 25175, 640, 16, 96, 48, 480, 11, 2, 31 }, + { "640x480@72", 31500, 640, 24, 40, 128, 480, 9, 3, 28 }, + { "640x480@75", 31500, 640, 16, 96, 48, 480, 11, 2, 32 }, + { "640x480@85", 36000, 640, 32, 48, 112, 480, 1, 3, 25 }, + { "800x600@56", 38100, 800, 32, 128, 128, 600, 1, 4, 14 }, + { "800x600@60", 40000, 800, 40, 128, 88 , 600, 1, 4, 23 }, + { "800x600@72", 50000, 800, 56, 120, 64 , 600, 37, 6, 23 }, + { "800x600@75", 49500, 800, 16, 80, 160, 600, 1, 2, 21 }, + { "800x600@85", 56250, 800, 32, 64, 152, 600, 1, 3, 27 }, + { "1024x768@60", 65000, 1024, 24, 136, 160, 768, 3, 6, 29 }, + { "1024x768@70", 75000, 1024, 24, 136, 144, 768, 3, 6, 29 }, + { "1024x768@75", 78750, 1024, 16, 96, 176, 768, 1, 3, 28 }, + { "1024x768@85", 94500, 1024, 48, 96, 208, 768, 1, 3, 36 }, + { "1280x1024@60", 108000, 1280, 48, 112, 248, 1024, 1, 3, 38 }, + { "1280x1024@75", 135000, 1280, 16, 144, 248, 1024, 1, 3, 38 }, + { "1280x1024@85", 157500, 1280, 64, 160, 224, 1024, 1, 3, 44 }, + { "1400x1050@60", 122610, 1400, 88, 152, 240, 1050, 1, 3, 33 }, + { "1400x1050@75", 155850, 1400, 96, 152, 248, 1050, 1, 3, 42 }, + { "1600x1200@60", 162000, 1600, 64, 192, 304, 1200, 1, 3, 46 }, + { "1600x1200@65", 175500, 1600, 64, 192, 304, 1200, 1, 3, 46 }, + { "1600x1200@70", 189000, 1600, 64, 192, 304, 1200, 1, 3, 46 }, + { "1600x1200@75", 202500, 1600, 64, 192, 304, 1200, 1, 3, 46 }, + { "1600x1200@85", 229500, 1600, 64, 192, 304, 1200, 1, 3, 46 }, + { "1792x1344@60", 204800, 1792, 128, 200, 328, 1344, 1, 3, 46 }, + { "1792x1344@75", 261000, 1792, 96, 216, 352, 1344, 1, 3, 69 }, + { "1856x1392@60", 218300, 1856, 96, 224, 352, 1392, 1, 3, 43 }, + { "1856x1392@75", 288000, 1856, 128, 224, 352, 1392, 1, 3, 104 }, + { "1920x1200@75", 193160, 1920, 128, 208, 336, 1200, 1, 3, 38 }, + { "1920x1440@60", 234000, 1920, 128, 208, 344, 1440, 1, 3, 56 }, + { "1920x1440@75", 297000, 1920, 144, 224, 352, 1440, 1, 3, 56 }, +}; + +#endif diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index e5dce5e..8e934a4 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -19,6 +19,8 @@ #define CONFIG_DOMAIN_PAGE 1 +#define CONFIG_VIDEO 1 + #define OPT_CONSOLE_STR "com1" #ifdef MAX_PHYS_CPUS -- 1.7.2.5
Stefano Stabellini
2013-Feb-14 17:32 UTC
Re: [PATCH v7 2/5] xen/arm: move setup_mm right after setup_pagetables
On Thu, 14 Feb 2013, Stefano Stabellini wrote:> At the moment we destroy the DTB mappings we have in setup_pagetables > and we restore them only in setup_mm. > > Move setup_mm right after setup_pagetables. > This ensures we have a valid DTB mapping while running the subsequent > initialization code. > > Changes in v7: > - turn more printk''s into early_printk.I forgot to mention in the changelog that I removed two printks from init_boot_pages.> Changes in v5: > - reword commit message; > - turn printk in setup_mm into an early_printk. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > --- > xen/arch/arm/setup.c | 7 +++---- > xen/common/page_alloc.c | 6 ------ > 2 files changed, 3 insertions(+), 10 deletions(-) > > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index e1ab7f6..c568be5 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -246,11 +246,11 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t dtb_size) > } while ( xenheap_pages > 128<<(20-PAGE_SHIFT) ); > > if ( ! e ) > - panic("Not not enough space for xenheap\n"); > + early_panic("Not not enough space for xenheap\n"); > > domheap_pages = heap_pages - xenheap_pages; > > - printk("Xen heap: %lu pages Dom heap: %lu pages\n", xenheap_pages, domheap_pages); > + early_printk("Xen heap: %lu pages Dom heap: %lu pages\n", xenheap_pages, domheap_pages); > > setup_xenheap_mappings((e >> PAGE_SHIFT) - xenheap_pages, xenheap_pages); > > @@ -349,6 +349,7 @@ void __init start_xen(unsigned long boot_phys_offset, > cmdline_parse(device_tree_bootargs(fdt)); > > setup_pagetables(boot_phys_offset, get_xen_paddr()); > + setup_mm(atag_paddr, fdt_size); > > #ifdef EARLY_UART_ADDRESS > /* TODO Need to get device tree or command line for UART address */ > @@ -366,8 +367,6 @@ void __init start_xen(unsigned long boot_phys_offset, > set_current((struct vcpu *)0xfffff000); /* debug sanity */ > idle_vcpu[0] = current; > > - setup_mm(atag_paddr, fdt_size); > - > /* Setup Hyp vector base */ > WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR); > printk("Set hyp vector base to %"PRIx32" (expected %p)\n", > diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c > index 6b8bc39..6c2215b 100644 > --- a/xen/common/page_alloc.c > +++ b/xen/common/page_alloc.c > @@ -182,12 +182,6 @@ void __init init_boot_pages(paddr_t ps, paddr_t pe) > else if ( *p != ''\0'' ) > break; > > - if ( bad_epfn == bad_spfn ) > - printk("Marking page %lx as bad\n", bad_spfn); > - else > - printk("Marking pages %lx through %lx as bad\n", > - bad_spfn, bad_epfn); > - > bootmem_region_zap(bad_spfn, bad_epfn+1); > } > } > -- > 1.7.2.5 >
Ian Campbell
2013-Feb-15 12:41 UTC
Re: [PATCH v7 1/5] xen: introduce a generic framebuffer driver
Keir, are you OK with this change? On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote:> Abstract away from vesa.c the funcions to handle a linear framebuffer > and print characters to it. > Make use of the new functions in vesa.c. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > Acked-by: Jan Beulich <JBeulich@suse.com> > > Changes in v6: > - remove useless initializations to NULL in lfb_init; > - more compact checks in lfb_init. > > Changes in v5: > - remove lfb_alloc and the now unused __initdata variables; > - fix indentation and long lines. > > Changes in v4: > - squash the vesa.c changes into this patch; > - rename fb* to lfb*; > - pass a pointer to fb_init; > - use %u for screen dimensions; > - specify loglevel in printk; > - call fb_free on error in fb_alloc; > - no __init on declarations; > - do not break messages to fit 80 columns. > --- > xen/drivers/video/Makefile | 1 + > xen/drivers/video/lfb.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ > xen/drivers/video/lfb.h | 46 +++++++++++ > xen/drivers/video/vesa.c | 177 ++++++------------------------------------ > 4 files changed, 254 insertions(+), 153 deletions(-) > create mode 100644 xen/drivers/video/lfb.c > create mode 100644 xen/drivers/video/lfb.h > > diff --git a/xen/drivers/video/Makefile b/xen/drivers/video/Makefile > index 2993c39..77f9d5d 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) += lfb.o > obj-$(HAS_VGA) += vesa.o > diff --git a/xen/drivers/video/lfb.c b/xen/drivers/video/lfb.c > new file mode 100644 > index 0000000..cc7f7ac > --- /dev/null > +++ b/xen/drivers/video/lfb.c > @@ -0,0 +1,183 @@ > +/****************************************************************************** > + * lfb.c > + * > + * linear frame buffer handling. > + */ > + > +#include <xen/config.h> > +#include <xen/kernel.h> > +#include <xen/lib.h> > +#include <xen/errno.h> > +#include "lfb.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 > + > +struct lfb_status { > + struct lfb_prop lfbp; > + > + unsigned char *lbuf, *text_buf; > + unsigned int *line_len; > + unsigned int xpos, ypos; > +}; > +static struct lfb_status lfb; > + > +static void lfb_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 = (lfb.lfbp.bits_per_pixel + 7) >> 3; > + > + for ( i = 0; i < lfb.lfbp.font->height; i++ ) > + { > + unsigned char *ptr = lfb.lbuf; > + > + for ( j = 0; j < nr_chars; j++ ) > + { > + const unsigned char *bits = lfb.lfbp.font->data; > + bits += ((text_line[j] * lfb.lfbp.font->height + i) * > + ((lfb.lfbp.font->width + 7) >> 3)); > + for ( b = lfb.lfbp.font->width; b--; ) > + { > + pixel = (*bits & (1u<<b)) ? lfb.lfbp.pixel_on : 0; > + memcpy(ptr, &pixel, bpp); > + ptr += bpp; > + } > + } > + > + memset(ptr, 0, (lfb.lfbp.width - nr_chars * lfb.lfbp.font->width) * bpp); > + memcpy(video_line, lfb.lbuf, nr_cells * lfb.lfbp.font->width * bpp); > + video_line += lfb.lfbp.bytes_per_line; > + } > +} > + > +/* Fast mode which redraws all modified parts of a 2D text buffer. */ > +void lfb_redraw_puts(const char *s) > +{ > + unsigned int i, min_redraw_y = lfb.ypos; > + char c; > + > + /* Paste characters into text buffer. */ > + while ( (c = *s++) != ''\0'' ) > + { > + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) > + { > + if ( ++lfb.ypos >= lfb.lfbp.text_rows ) > + { > + min_redraw_y = 0; > + lfb.ypos = lfb.lfbp.text_rows - 1; > + memmove(lfb.text_buf, lfb.text_buf + lfb.lfbp.text_columns, > + lfb.ypos * lfb.lfbp.text_columns); > + memset(lfb.text_buf + lfb.ypos * lfb.lfbp.text_columns, 0, lfb.xpos); > + } > + lfb.xpos = 0; > + } > + > + if ( c != ''\n'' ) > + lfb.text_buf[lfb.xpos++ + lfb.ypos * lfb.lfbp.text_columns] = c; > + } > + > + /* Render modified section of text buffer to VESA linear framebuffer. */ > + for ( i = min_redraw_y; i <= lfb.ypos; i++ ) > + { > + const unsigned char *line = lfb.text_buf + i * lfb.lfbp.text_columns; > + unsigned int width; > + > + for ( width = lfb.lfbp.text_columns; width; --width ) > + if ( line[width - 1] ) > + break; > + lfb_show_line(line, > + lfb.lfbp.lfb + i * lfb.lfbp.font->height * lfb.lfbp.bytes_per_line, > + width, max(lfb.line_len[i], width)); > + lfb.line_len[i] = width; > + } > + > + lfb.lfbp.flush(); > +} > + > +/* Slower line-based scroll mode which interacts better with dom0. */ > +void lfb_scroll_puts(const char *s) > +{ > + unsigned int i; > + char c; > + > + while ( (c = *s++) != ''\0'' ) > + { > + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) > + { > + unsigned int bytes = (lfb.lfbp.width * > + ((lfb.lfbp.bits_per_pixel + 7) >> 3)); > + unsigned char *src = lfb.lfbp.lfb + lfb.lfbp.font->height * lfb.lfbp.bytes_per_line; > + unsigned char *dst = lfb.lfbp.lfb; > + > + /* New line: scroll all previous rows up one line. */ > + for ( i = lfb.lfbp.font->height; i < lfb.lfbp.height; i++ ) > + { > + memcpy(dst, src, bytes); > + src += lfb.lfbp.bytes_per_line; > + dst += lfb.lfbp.bytes_per_line; > + } > + > + /* Render new line. */ > + lfb_show_line( > + lfb.text_buf, > + lfb.lfbp.lfb + (lfb.lfbp.text_rows-1) * lfb.lfbp.font->height * > + lfb.lfbp.bytes_per_line, > + lfb.xpos, lfb.lfbp.text_columns); > + > + lfb.xpos = 0; > + } > + > + if ( c != ''\n'' ) > + lfb.text_buf[lfb.xpos++] = c; > + } > + > + lfb.lfbp.flush(); > +} > + > +void lfb_carriage_return(void) > +{ > + lfb.xpos = 0; > +} > + > +int __init lfb_init(struct lfb_prop *lfbp) > +{ > + if ( lfbp->width > MAX_XRES || lfbp->height > MAX_YRES ) > + { > + printk(XENLOG_WARNING "Couldn''t initialize a %ux%u framebuffer early.\n", > + lfbp->width, lfbp->height); > + return -EINVAL; > + } > + > + lfb.lfbp = *lfbp; > + > + lfb.lbuf = xmalloc_bytes(lfb.lfbp.bytes_per_line); > + lfb.text_buf = xzalloc_bytes(lfb.lfbp.text_columns * lfb.lfbp.text_rows); > + lfb.line_len = xzalloc_array(unsigned int, lfb.lfbp.text_columns); > + > + if ( !lfb.lbuf || !lfb.text_buf || !lfb.line_len ) > + goto fail; > + > + return 0; > + > +fail: > + printk(XENLOG_ERR "Couldn''t allocate enough memory to drive the framebuffer\n"); > + lfb_free(); > + > + return -ENOMEM; > +} > + > +void lfb_free(void) > +{ > + xfree(lfb.lbuf); > + xfree(lfb.text_buf); > + xfree(lfb.line_len); > +} > diff --git a/xen/drivers/video/lfb.h b/xen/drivers/video/lfb.h > new file mode 100644 > index 0000000..ac40a66 > --- /dev/null > +++ b/xen/drivers/video/lfb.h > @@ -0,0 +1,46 @@ > +/* > + * xen/drivers/video/lfb.h > + * > + * Cross-platform framebuffer library > + * > + * Stefano Stabellini <stefano.stabellini@eu.citrix.com> > + * Copyright (c) 2013 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_LFB_H > +#define _XEN_LFB_H > + > +#include <xen/init.h> > + > +struct lfb_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 lfb_redraw_puts(const char *s); > +void lfb_scroll_puts(const char *s); > +void lfb_carriage_return(void); > +void lfb_free(void); > + > +/* initialize the framebuffer */ > +int lfb_init(struct lfb_prop *lfbp); > + > +#endif > diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c > index aaf8b23..1144f76 100644 > --- a/xen/drivers/video/vesa.c > +++ b/xen/drivers/video/vesa.c > @@ -13,20 +13,15 @@ > #include <asm/io.h> > #include <asm/page.h> > #include "font.h" > +#include "lfb.h" > > #define vlfb_info vga_console_info.u.vesa_lfb > -#define text_columns (vlfb_info.width / font->width) > -#define text_rows (vlfb_info.height / font->height) > > -static void vesa_redraw_puts(const char *s); > -static void vesa_scroll_puts(const char *s); > +static void lfb_flush(void); > > -static unsigned char *lfb, *lbuf, *text_buf; > -static unsigned int *__initdata line_len; > +static unsigned char *lfb; > static const struct font_desc *font; > static bool_t vga_compat; > -static unsigned int pixel_on; > -static unsigned int xpos, ypos; > > static unsigned int vram_total; > integer_param("vesa-ram", vram_total); > @@ -87,29 +82,26 @@ void __init vesa_early_init(void) > > void __init vesa_init(void) > { > - if ( !font ) > - goto fail; > - > - lbuf = xmalloc_bytes(vlfb_info.bytes_per_line); > - if ( !lbuf ) > - goto fail; > + struct lfb_prop lfbp; > > - text_buf = xzalloc_bytes(text_columns * text_rows); > - if ( !text_buf ) > - goto fail; > + if ( !font ) > + return; > > - line_len = xzalloc_array(unsigned int, text_columns); > - if ( !line_len ) > - goto fail; > + lfbp.font = font; > + lfbp.bits_per_pixel = vlfb_info.bits_per_pixel; > + lfbp.bytes_per_line = vlfb_info.bytes_per_line; > + lfbp.width = vlfb_info.width; > + lfbp.height = vlfb_info.height; > + lfbp.flush = lfb_flush; > + lfbp.text_columns = vlfb_info.width / font->width; > + lfbp.text_rows = vlfb_info.height / font->height; > > - lfb = ioremap(vlfb_info.lfb_base, vram_remap); > + lfbp.lfb = lfb = ioremap(vlfb_info.lfb_base, vram_remap); > if ( !lfb ) > - goto fail; > + return; > > memset(lfb, 0, vram_remap); > > - video_puts = vesa_redraw_puts; > - > printk(XENLOG_INFO "vesafb: framebuffer at %#x, mapped to 0x%p, " > "using %uk, total %uk\n", > vlfb_info.lfb_base, lfb, > @@ -131,7 +123,7 @@ void __init vesa_init(void) > { > /* Light grey in truecolor. */ > unsigned int grey = 0xaaaaaaaa; > - pixel_on > + fbp.pixel_on > ((grey >> (32 - vlfb_info. red_size)) << vlfb_info. red_pos) | > ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) | > ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos); > @@ -139,15 +131,12 @@ void __init vesa_init(void) > else > { > /* White(ish) in default pseudocolor palette. */ > - pixel_on = 7; > + fbp.pixel_on = 7; > } > > - return; > - > - fail: > - xfree(lbuf); > - xfree(text_buf); > - xfree(line_len); > + if ( lfb_init(&lfbp) < 0 ) > + return; > + video_puts = lfb_redraw_puts; > } > > #include <asm/mtrr.h> > @@ -192,8 +181,8 @@ void __init vesa_endboot(bool_t keep) > { > if ( keep ) > { > - xpos = 0; > - video_puts = vesa_scroll_puts; > + video_puts = lfb_scroll_puts; > + lfb_carriage_return(); > } > else > { > @@ -202,124 +191,6 @@ void __init vesa_endboot(bool_t keep) > memset(lfb + i * vlfb_info.bytes_per_line, 0, > vlfb_info.width * bpp); > lfb_flush(); > + lfb_free(); > } > - > - xfree(line_len); > -} > - > -/* Render one line of text to given linear framebuffer line. */ > -static void vesa_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 = (vlfb_info.bits_per_pixel + 7) >> 3; > - > - for ( i = 0; i < font->height; i++ ) > - { > - unsigned char *ptr = lbuf; > - > - for ( j = 0; j < nr_chars; j++ ) > - { > - const unsigned char *bits = font->data; > - bits += ((text_line[j] * font->height + i) * > - ((font->width + 7) >> 3)); > - for ( b = font->width; b--; ) > - { > - pixel = (*bits & (1u<<b)) ? pixel_on : 0; > - memcpy(ptr, &pixel, bpp); > - ptr += bpp; > - } > - } > - > - memset(ptr, 0, (vlfb_info.width - nr_chars * font->width) * bpp); > - memcpy(video_line, lbuf, nr_cells * font->width * bpp); > - video_line += vlfb_info.bytes_per_line; > - } > -} > - > -/* Fast mode which redraws all modified parts of a 2D text buffer. */ > -static void __init vesa_redraw_puts(const char *s) > -{ > - unsigned int i, min_redraw_y = ypos; > - char c; > - > - /* Paste characters into text buffer. */ > - while ( (c = *s++) != ''\0'' ) > - { > - if ( (c == ''\n'') || (xpos >= text_columns) ) > - { > - if ( ++ypos >= text_rows ) > - { > - min_redraw_y = 0; > - ypos = text_rows - 1; > - memmove(text_buf, text_buf + text_columns, > - ypos * text_columns); > - memset(text_buf + ypos * text_columns, 0, xpos); > - } > - xpos = 0; > - } > - > - if ( c != ''\n'' ) > - text_buf[xpos++ + ypos * text_columns] = c; > - } > - > - /* Render modified section of text buffer to VESA linear framebuffer. */ > - for ( i = min_redraw_y; i <= ypos; i++ ) > - { > - const unsigned char *line = text_buf + i * text_columns; > - unsigned int width; > - > - for ( width = text_columns; width; --width ) > - if ( line[width - 1] ) > - break; > - vesa_show_line(line, > - lfb + i * font->height * vlfb_info.bytes_per_line, > - width, max(line_len[i], width)); > - line_len[i] = width; > - } > - > - lfb_flush(); > -} > - > -/* Slower line-based scroll mode which interacts better with dom0. */ > -static void vesa_scroll_puts(const char *s) > -{ > - unsigned int i; > - char c; > - > - while ( (c = *s++) != ''\0'' ) > - { > - if ( (c == ''\n'') || (xpos >= text_columns) ) > - { > - unsigned int bytes = (vlfb_info.width * > - ((vlfb_info.bits_per_pixel + 7) >> 3)); > - unsigned char *src = lfb + font->height * vlfb_info.bytes_per_line; > - unsigned char *dst = lfb; > - > - /* New line: scroll all previous rows up one line. */ > - for ( i = font->height; i < vlfb_info.height; i++ ) > - { > - memcpy(dst, src, bytes); > - src += vlfb_info.bytes_per_line; > - dst += vlfb_info.bytes_per_line; > - } > - > - /* Render new line. */ > - vesa_show_line( > - text_buf, > - lfb + (text_rows-1) * font->height * vlfb_info.bytes_per_line, > - xpos, text_columns); > - > - xpos = 0; > - } > - > - if ( c != ''\n'' ) > - text_buf[xpos++] = c; > - } > - > - lfb_flush(); > } > -- > 1.7.2.5 >
Keir Fraser
2013-Feb-15 13:15 UTC
Re: [PATCH v7 1/5] xen: introduce a generic framebuffer driver
Yep Acked-by: Keir Fraser <keir@xen.org> On 15/02/2013 12:41, "Ian Campbell" <Ian.Campbell@citrix.com> wrote:> Keir, are you OK with this change? > > On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote: >> Abstract away from vesa.c the funcions to handle a linear framebuffer >> and print characters to it. >> Make use of the new functions in vesa.c. >> >> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> >> Acked-by: Jan Beulich <JBeulich@suse.com> >> >> Changes in v6: >> - remove useless initializations to NULL in lfb_init; >> - more compact checks in lfb_init. >> >> Changes in v5: >> - remove lfb_alloc and the now unused __initdata variables; >> - fix indentation and long lines. >> >> Changes in v4: >> - squash the vesa.c changes into this patch; >> - rename fb* to lfb*; >> - pass a pointer to fb_init; >> - use %u for screen dimensions; >> - specify loglevel in printk; >> - call fb_free on error in fb_alloc; >> - no __init on declarations; >> - do not break messages to fit 80 columns. >> --- >> xen/drivers/video/Makefile | 1 + >> xen/drivers/video/lfb.c | 183 >> ++++++++++++++++++++++++++++++++++++++++++++ >> xen/drivers/video/lfb.h | 46 +++++++++++ >> xen/drivers/video/vesa.c | 177 ++++++------------------------------------ >> 4 files changed, 254 insertions(+), 153 deletions(-) >> create mode 100644 xen/drivers/video/lfb.c >> create mode 100644 xen/drivers/video/lfb.h >> >> diff --git a/xen/drivers/video/Makefile b/xen/drivers/video/Makefile >> index 2993c39..77f9d5d 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) += lfb.o >> obj-$(HAS_VGA) += vesa.o >> diff --git a/xen/drivers/video/lfb.c b/xen/drivers/video/lfb.c >> new file mode 100644 >> index 0000000..cc7f7ac >> --- /dev/null >> +++ b/xen/drivers/video/lfb.c >> @@ -0,0 +1,183 @@ >> +/*************************************************************************** >> *** >> + * lfb.c >> + * >> + * linear frame buffer handling. >> + */ >> + >> +#include <xen/config.h> >> +#include <xen/kernel.h> >> +#include <xen/lib.h> >> +#include <xen/errno.h> >> +#include "lfb.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 >> + >> +struct lfb_status { >> + struct lfb_prop lfbp; >> + >> + unsigned char *lbuf, *text_buf; >> + unsigned int *line_len; >> + unsigned int xpos, ypos; >> +}; >> +static struct lfb_status lfb; >> + >> +static void lfb_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 = (lfb.lfbp.bits_per_pixel + 7) >> 3; >> + >> + for ( i = 0; i < lfb.lfbp.font->height; i++ ) >> + { >> + unsigned char *ptr = lfb.lbuf; >> + >> + for ( j = 0; j < nr_chars; j++ ) >> + { >> + const unsigned char *bits = lfb.lfbp.font->data; >> + bits += ((text_line[j] * lfb.lfbp.font->height + i) * >> + ((lfb.lfbp.font->width + 7) >> 3)); >> + for ( b = lfb.lfbp.font->width; b--; ) >> + { >> + pixel = (*bits & (1u<<b)) ? lfb.lfbp.pixel_on : 0; >> + memcpy(ptr, &pixel, bpp); >> + ptr += bpp; >> + } >> + } >> + >> + memset(ptr, 0, (lfb.lfbp.width - nr_chars * lfb.lfbp.font->width) * >> bpp); >> + memcpy(video_line, lfb.lbuf, nr_cells * lfb.lfbp.font->width * bpp); >> + video_line += lfb.lfbp.bytes_per_line; >> + } >> +} >> + >> +/* Fast mode which redraws all modified parts of a 2D text buffer. */ >> +void lfb_redraw_puts(const char *s) >> +{ >> + unsigned int i, min_redraw_y = lfb.ypos; >> + char c; >> + >> + /* Paste characters into text buffer. */ >> + while ( (c = *s++) != ''\0'' ) >> + { >> + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) >> + { >> + if ( ++lfb.ypos >= lfb.lfbp.text_rows ) >> + { >> + min_redraw_y = 0; >> + lfb.ypos = lfb.lfbp.text_rows - 1; >> + memmove(lfb.text_buf, lfb.text_buf + lfb.lfbp.text_columns, >> + lfb.ypos * lfb.lfbp.text_columns); >> + memset(lfb.text_buf + lfb.ypos * lfb.lfbp.text_columns, 0, >> lfb.xpos); >> + } >> + lfb.xpos = 0; >> + } >> + >> + if ( c != ''\n'' ) >> + lfb.text_buf[lfb.xpos++ + lfb.ypos * lfb.lfbp.text_columns] = c; >> + } >> + >> + /* Render modified section of text buffer to VESA linear framebuffer. */ >> + for ( i = min_redraw_y; i <= lfb.ypos; i++ ) >> + { >> + const unsigned char *line = lfb.text_buf + i * >> lfb.lfbp.text_columns; >> + unsigned int width; >> + >> + for ( width = lfb.lfbp.text_columns; width; --width ) >> + if ( line[width - 1] ) >> + break; >> + lfb_show_line(line, >> + lfb.lfbp.lfb + i * lfb.lfbp.font->height * >> lfb.lfbp.bytes_per_line, >> + width, max(lfb.line_len[i], width)); >> + lfb.line_len[i] = width; >> + } >> + >> + lfb.lfbp.flush(); >> +} >> + >> +/* Slower line-based scroll mode which interacts better with dom0. */ >> +void lfb_scroll_puts(const char *s) >> +{ >> + unsigned int i; >> + char c; >> + >> + while ( (c = *s++) != ''\0'' ) >> + { >> + if ( (c == ''\n'') || (lfb.xpos >= lfb.lfbp.text_columns) ) >> + { >> + unsigned int bytes = (lfb.lfbp.width * >> + ((lfb.lfbp.bits_per_pixel + 7) >> 3)); >> + unsigned char *src = lfb.lfbp.lfb + lfb.lfbp.font->height * >> lfb.lfbp.bytes_per_line; >> + unsigned char *dst = lfb.lfbp.lfb; >> + >> + /* New line: scroll all previous rows up one line. */ >> + for ( i = lfb.lfbp.font->height; i < lfb.lfbp.height; i++ ) >> + { >> + memcpy(dst, src, bytes); >> + src += lfb.lfbp.bytes_per_line; >> + dst += lfb.lfbp.bytes_per_line; >> + } >> + >> + /* Render new line. */ >> + lfb_show_line( >> + lfb.text_buf, >> + lfb.lfbp.lfb + (lfb.lfbp.text_rows-1) * >> lfb.lfbp.font->height * >> + lfb.lfbp.bytes_per_line, >> + lfb.xpos, lfb.lfbp.text_columns); >> + >> + lfb.xpos = 0; >> + } >> + >> + if ( c != ''\n'' ) >> + lfb.text_buf[lfb.xpos++] = c; >> + } >> + >> + lfb.lfbp.flush(); >> +} >> + >> +void lfb_carriage_return(void) >> +{ >> + lfb.xpos = 0; >> +} >> + >> +int __init lfb_init(struct lfb_prop *lfbp) >> +{ >> + if ( lfbp->width > MAX_XRES || lfbp->height > MAX_YRES ) >> + { >> + printk(XENLOG_WARNING "Couldn''t initialize a %ux%u framebuffer >> early.\n", >> + lfbp->width, lfbp->height); >> + return -EINVAL; >> + } >> + >> + lfb.lfbp = *lfbp; >> + >> + lfb.lbuf = xmalloc_bytes(lfb.lfbp.bytes_per_line); >> + lfb.text_buf = xzalloc_bytes(lfb.lfbp.text_columns * >> lfb.lfbp.text_rows); >> + lfb.line_len = xzalloc_array(unsigned int, lfb.lfbp.text_columns); >> + >> + if ( !lfb.lbuf || !lfb.text_buf || !lfb.line_len ) >> + goto fail; >> + >> + return 0; >> + >> +fail: >> + printk(XENLOG_ERR "Couldn''t allocate enough memory to drive the >> framebuffer\n"); >> + lfb_free(); >> + >> + return -ENOMEM; >> +} >> + >> +void lfb_free(void) >> +{ >> + xfree(lfb.lbuf); >> + xfree(lfb.text_buf); >> + xfree(lfb.line_len); >> +} >> diff --git a/xen/drivers/video/lfb.h b/xen/drivers/video/lfb.h >> new file mode 100644 >> index 0000000..ac40a66 >> --- /dev/null >> +++ b/xen/drivers/video/lfb.h >> @@ -0,0 +1,46 @@ >> +/* >> + * xen/drivers/video/lfb.h >> + * >> + * Cross-platform framebuffer library >> + * >> + * Stefano Stabellini <stefano.stabellini@eu.citrix.com> >> + * Copyright (c) 2013 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_LFB_H >> +#define _XEN_LFB_H >> + >> +#include <xen/init.h> >> + >> +struct lfb_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 lfb_redraw_puts(const char *s); >> +void lfb_scroll_puts(const char *s); >> +void lfb_carriage_return(void); >> +void lfb_free(void); >> + >> +/* initialize the framebuffer */ >> +int lfb_init(struct lfb_prop *lfbp); >> + >> +#endif >> diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c >> index aaf8b23..1144f76 100644 >> --- a/xen/drivers/video/vesa.c >> +++ b/xen/drivers/video/vesa.c >> @@ -13,20 +13,15 @@ >> #include <asm/io.h> >> #include <asm/page.h> >> #include "font.h" >> +#include "lfb.h" >> >> #define vlfb_info vga_console_info.u.vesa_lfb >> -#define text_columns (vlfb_info.width / font->width) >> -#define text_rows (vlfb_info.height / font->height) >> >> -static void vesa_redraw_puts(const char *s); >> -static void vesa_scroll_puts(const char *s); >> +static void lfb_flush(void); >> >> -static unsigned char *lfb, *lbuf, *text_buf; >> -static unsigned int *__initdata line_len; >> +static unsigned char *lfb; >> static const struct font_desc *font; >> static bool_t vga_compat; >> -static unsigned int pixel_on; >> -static unsigned int xpos, ypos; >> >> static unsigned int vram_total; >> integer_param("vesa-ram", vram_total); >> @@ -87,29 +82,26 @@ void __init vesa_early_init(void) >> >> void __init vesa_init(void) >> { >> - if ( !font ) >> - goto fail; >> - >> - lbuf = xmalloc_bytes(vlfb_info.bytes_per_line); >> - if ( !lbuf ) >> - goto fail; >> + struct lfb_prop lfbp; >> >> - text_buf = xzalloc_bytes(text_columns * text_rows); >> - if ( !text_buf ) >> - goto fail; >> + if ( !font ) >> + return; >> >> - line_len = xzalloc_array(unsigned int, text_columns); >> - if ( !line_len ) >> - goto fail; >> + lfbp.font = font; >> + lfbp.bits_per_pixel = vlfb_info.bits_per_pixel; >> + lfbp.bytes_per_line = vlfb_info.bytes_per_line; >> + lfbp.width = vlfb_info.width; >> + lfbp.height = vlfb_info.height; >> + lfbp.flush = lfb_flush; >> + lfbp.text_columns = vlfb_info.width / font->width; >> + lfbp.text_rows = vlfb_info.height / font->height; >> >> - lfb = ioremap(vlfb_info.lfb_base, vram_remap); >> + lfbp.lfb = lfb = ioremap(vlfb_info.lfb_base, vram_remap); >> if ( !lfb ) >> - goto fail; >> + return; >> >> memset(lfb, 0, vram_remap); >> >> - video_puts = vesa_redraw_puts; >> - >> printk(XENLOG_INFO "vesafb: framebuffer at %#x, mapped to 0x%p, " >> "using %uk, total %uk\n", >> vlfb_info.lfb_base, lfb, >> @@ -131,7 +123,7 @@ void __init vesa_init(void) >> { >> /* Light grey in truecolor. */ >> unsigned int grey = 0xaaaaaaaa; >> - pixel_on >> + fbp.pixel_on >> ((grey >> (32 - vlfb_info. red_size)) << vlfb_info. red_pos) | >> ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) | >> ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos); >> @@ -139,15 +131,12 @@ void __init vesa_init(void) >> else >> { >> /* White(ish) in default pseudocolor palette. */ >> - pixel_on = 7; >> + fbp.pixel_on = 7; >> } >> >> - return; >> - >> - fail: >> - xfree(lbuf); >> - xfree(text_buf); >> - xfree(line_len); >> + if ( lfb_init(&lfbp) < 0 ) >> + return; >> + video_puts = lfb_redraw_puts; >> } >> >> #include <asm/mtrr.h> >> @@ -192,8 +181,8 @@ void __init vesa_endboot(bool_t keep) >> { >> if ( keep ) >> { >> - xpos = 0; >> - video_puts = vesa_scroll_puts; >> + video_puts = lfb_scroll_puts; >> + lfb_carriage_return(); >> } >> else >> { >> @@ -202,124 +191,6 @@ void __init vesa_endboot(bool_t keep) >> memset(lfb + i * vlfb_info.bytes_per_line, 0, >> vlfb_info.width * bpp); >> lfb_flush(); >> + lfb_free(); >> } >> - >> - xfree(line_len); >> -} >> - >> -/* Render one line of text to given linear framebuffer line. */ >> -static void vesa_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 = (vlfb_info.bits_per_pixel + 7) >> 3; >> - >> - for ( i = 0; i < font->height; i++ ) >> - { >> - unsigned char *ptr = lbuf; >> - >> - for ( j = 0; j < nr_chars; j++ ) >> - { >> - const unsigned char *bits = font->data; >> - bits += ((text_line[j] * font->height + i) * >> - ((font->width + 7) >> 3)); >> - for ( b = font->width; b--; ) >> - { >> - pixel = (*bits & (1u<<b)) ? pixel_on : 0; >> - memcpy(ptr, &pixel, bpp); >> - ptr += bpp; >> - } >> - } >> - >> - memset(ptr, 0, (vlfb_info.width - nr_chars * font->width) * bpp); >> - memcpy(video_line, lbuf, nr_cells * font->width * bpp); >> - video_line += vlfb_info.bytes_per_line; >> - } >> -} >> - >> -/* Fast mode which redraws all modified parts of a 2D text buffer. */ >> -static void __init vesa_redraw_puts(const char *s) >> -{ >> - unsigned int i, min_redraw_y = ypos; >> - char c; >> - >> - /* Paste characters into text buffer. */ >> - while ( (c = *s++) != ''\0'' ) >> - { >> - if ( (c == ''\n'') || (xpos >= text_columns) ) >> - { >> - if ( ++ypos >= text_rows ) >> - { >> - min_redraw_y = 0; >> - ypos = text_rows - 1; >> - memmove(text_buf, text_buf + text_columns, >> - ypos * text_columns); >> - memset(text_buf + ypos * text_columns, 0, xpos); >> - } >> - xpos = 0; >> - } >> - >> - if ( c != ''\n'' ) >> - text_buf[xpos++ + ypos * text_columns] = c; >> - } >> - >> - /* Render modified section of text buffer to VESA linear framebuffer. */ >> - for ( i = min_redraw_y; i <= ypos; i++ ) >> - { >> - const unsigned char *line = text_buf + i * text_columns; >> - unsigned int width; >> - >> - for ( width = text_columns; width; --width ) >> - if ( line[width - 1] ) >> - break; >> - vesa_show_line(line, >> - lfb + i * font->height * vlfb_info.bytes_per_line, >> - width, max(line_len[i], width)); >> - line_len[i] = width; >> - } >> - >> - lfb_flush(); >> -} >> - >> -/* Slower line-based scroll mode which interacts better with dom0. */ >> -static void vesa_scroll_puts(const char *s) >> -{ >> - unsigned int i; >> - char c; >> - >> - while ( (c = *s++) != ''\0'' ) >> - { >> - if ( (c == ''\n'') || (xpos >= text_columns) ) >> - { >> - unsigned int bytes = (vlfb_info.width * >> - ((vlfb_info.bits_per_pixel + 7) >> 3)); >> - unsigned char *src = lfb + font->height * >> vlfb_info.bytes_per_line; >> - unsigned char *dst = lfb; >> - >> - /* New line: scroll all previous rows up one line. */ >> - for ( i = font->height; i < vlfb_info.height; i++ ) >> - { >> - memcpy(dst, src, bytes); >> - src += vlfb_info.bytes_per_line; >> - dst += vlfb_info.bytes_per_line; >> - } >> - >> - /* Render new line. */ >> - vesa_show_line( >> - text_buf, >> - lfb + (text_rows-1) * font->height * >> vlfb_info.bytes_per_line, >> - xpos, text_columns); >> - >> - xpos = 0; >> - } >> - >> - if ( c != ''\n'' ) >> - text_buf[xpos++] = c; >> - } >> - >> - lfb_flush(); >> } >> -- >> 1.7.2.5 >> > >
On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote:> Stefano Stabellini (5): > xen: introduce a generic framebuffer driverNeeded ack from Keir when I first went through my queue. He has given it now so I''ll go back to this one.> xen/arm: move setup_mm right after setup_pagetables > xen/device_tree: introduce find_compatible_node > xen/arm: introduce vexpress_syscfgAcked + applied these with s/atag_paddr/fdt_paddr/ since it was on top of " xen: arm: rename atag_paddr argument fdt_paddr"> xen/arm: introduce a driver for the ARM HDLCD controllerNeeds the first one. Ian.
Ian Campbell
2013-Feb-15 14:07 UTC
Re: [PATCH v7 1/5] xen: introduce a generic framebuffer driver
On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote:> xen/drivers/video/Makefile | 1 + > xen/drivers/video/lfb.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ > xen/drivers/video/lfb.h | 46 +++++++++++ > xen/drivers/video/vesa.c | 177 ++++++------------------------------------On x86_64; vesa.c: In function ‘vesa_init’: vesa.c:126: error: ‘fbp’ undeclared (first use in this function) vesa.c:126: error: (Each undeclared identifier is reported only once vesa.c:126: error: for each function it appears in.) I think this fixes it, if it does then I'm happy to role in as I apply. diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c index 1fbe959..575db62 100644 --- a/xen/drivers/video/vesa.c +++ b/xen/drivers/video/vesa.c @@ -123,7 +123,7 @@ void __init vesa_init(void) { /* Light grey in truecolor. */ unsigned int grey = 0xaaaaaaaa; - fbp.pixel_on + lfbp.pixel_on ((grey >> (32 - vlfb_info. red_size)) << vlfb_info. red_pos) | ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) | ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos); @@ -131,7 +131,7 @@ void __init vesa_init(void) else { /* White(ish) in default pseudocolor palette. */ - fbp.pixel_on = 7; + lfbp.pixel_on = 7; } if ( lfb_init(&lfbp) < 0 ) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Stefano Stabellini
2013-Feb-15 14:09 UTC
Re: [PATCH v7 1/5] xen: introduce a generic framebuffer driver
On Fri, 15 Feb 2013, Ian Campbell wrote:> On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote: > > xen/drivers/video/Makefile | 1 + > > xen/drivers/video/lfb.c | 183 ++++++++++++++++++++++++++++++++++++++++++++ > > xen/drivers/video/lfb.h | 46 +++++++++++ > > xen/drivers/video/vesa.c | 177 ++++++------------------------------------ > > On x86_64; > > vesa.c: In function ‘vesa_init’: > vesa.c:126: error: ‘fbp’ undeclared (first use in this function) > vesa.c:126: error: (Each undeclared identifier is reported only once > vesa.c:126: error: for each function it appears in.) > > I think this fixes it, if it does then I''m happy to role in as I apply.Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>> diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c > index 1fbe959..575db62 100644 > --- a/xen/drivers/video/vesa.c > +++ b/xen/drivers/video/vesa.c > @@ -123,7 +123,7 @@ void __init vesa_init(void) > { > /* Light grey in truecolor. */ > unsigned int grey = 0xaaaaaaaa; > - fbp.pixel_on > + lfbp.pixel_on > ((grey >> (32 - vlfb_info. red_size)) << vlfb_info. red_pos) | > ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) | > ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos); > @@ -131,7 +131,7 @@ void __init vesa_init(void) > else > { > /* White(ish) in default pseudocolor palette. */ > - fbp.pixel_on = 7; > + lfbp.pixel_on = 7; > } > > if ( lfb_init(&lfbp) < 0 ) > > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
On Thu, 2013-02-14 at 17:30 +0000, Stefano Stabellini wrote:> Stefano Stabellini (5): > xen: introduce a generic framebuffer driver > xen/arm: introduce a driver for the ARM HDLCD controllerI''ve now applied these as well, with the fixes to the first as previously discussed.
Apparently Analagous Threads
- [Bug 63263] New: X server crash in nouveau_xv.c:NVPutImage (NVCopyNV12ColorPlanes)
- [PATCH 1/2] exa: Pre-G80 tiling support.
- Bug report about Windows 7 pro 64 bit domU on xen-unstable dom0 with qemu traditional
- Device model failure: no longer running with HVM-Guest
- pci passthrough error "unknown command"pci-ins"