]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xen: allow enable use of VGA console on dom0
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Tue, 31 May 2011 14:50:10 +0000 (10:50 -0400)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Tue, 4 Dec 2012 17:32:58 +0000 (12:32 -0500)
Get the information about the VGA console hardware from Xen, and put
it into the form the bootloader normally generates, so that the rest
of the kernel can deal with VGA as usual.

[ Impact: make VGA console work in dom0 ]

Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
[v1: Rebased on 2.6.39]
[v2: Removed incorrect comments and fixed compile warnings]
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
(cherry picked from commit c2419b4a4727f67af2fc2cd68b0d878b75e781bb)

Conflicts:
arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/xen-ops.h

arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
arch/x86/xen/vga.c [new file with mode: 0644]
arch/x86/xen/xen-ops.h
include/xen/interface/xen.h

index 43e1708b7067cfc7aa01394576c68ebc0f502fd4..96ab2c09cb68e01bdb267c76a96f72ad93fde11b 100644 (file)
@@ -20,5 +20,5 @@ obj-$(CONFIG_EVENT_TRACING) += trace.o
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
 obj-$(CONFIG_XEN_DEBUG_FS)     += debugfs.o
-obj-$(CONFIG_XEN_DOM0)         += apic.o
+obj-$(CONFIG_XEN_DOM0)         += apic.o vga.o
 obj-$(CONFIG_SWIOTLB_XEN)      += pci-swiotlb-xen.o
index 3c06079064327836d832a4cd5d3c1a546c176b8c..09d8feb28cc0eef0799aee9c772c7a9c28418826 100644 (file)
@@ -1487,8 +1487,15 @@ asmlinkage void __init xen_start_kernel(void)
                if (pci_xen)
                        x86_init.pci.arch_init = pci_xen_init;
        } else {
-               xen_init_apic();
+               const struct dom0_vga_console_info *info =
+                       (void *)((char *)xen_start_info +
+                                xen_start_info->console.dom0.info_off);
+
+               xen_init_vga(info, xen_start_info->console.dom0.info_size);
+               xen_start_info->console.domU.mfn = 0;
+               xen_start_info->console.domU.evtchn = 0;
 
+               xen_init_apic();
                /* Make sure ACS will be enabled */
                pci_request_acs();
        }
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
new file mode 100644 (file)
index 0000000..1cd7f4d
--- /dev/null
@@ -0,0 +1,67 @@
+#include <linux/screen_info.h>
+#include <linux/init.h>
+
+#include <asm/bootparam.h>
+#include <asm/setup.h>
+
+#include <xen/interface/xen.h>
+
+#include "xen-ops.h"
+
+void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
+{
+       struct screen_info *screen_info = &boot_params.screen_info;
+
+       /* This is drawn from a dump from vgacon:startup in
+        * standard Linux. */
+       screen_info->orig_video_mode = 3;
+       screen_info->orig_video_isVGA = 1;
+       screen_info->orig_video_lines = 25;
+       screen_info->orig_video_cols = 80;
+       screen_info->orig_video_ega_bx = 3;
+       screen_info->orig_video_points = 16;
+       screen_info->orig_y = screen_info->orig_video_lines - 1;
+
+       switch (info->video_type) {
+       case XEN_VGATYPE_TEXT_MODE_3:
+               if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3)
+                   + sizeof(info->u.text_mode_3))
+                       break;
+               screen_info->orig_video_lines = info->u.text_mode_3.rows;
+               screen_info->orig_video_cols = info->u.text_mode_3.columns;
+               screen_info->orig_x = info->u.text_mode_3.cursor_x;
+               screen_info->orig_y = info->u.text_mode_3.cursor_y;
+               screen_info->orig_video_points =
+                       info->u.text_mode_3.font_height;
+               break;
+
+       case XEN_VGATYPE_VESA_LFB:
+               if (size < offsetof(struct dom0_vga_console_info,
+                                   u.vesa_lfb.gbl_caps))
+                       break;
+               screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB;
+               screen_info->lfb_width = info->u.vesa_lfb.width;
+               screen_info->lfb_height = info->u.vesa_lfb.height;
+               screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel;
+               screen_info->lfb_base = info->u.vesa_lfb.lfb_base;
+               screen_info->lfb_size = info->u.vesa_lfb.lfb_size;
+               screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line;
+               screen_info->red_size = info->u.vesa_lfb.red_size;
+               screen_info->red_pos = info->u.vesa_lfb.red_pos;
+               screen_info->green_size = info->u.vesa_lfb.green_size;
+               screen_info->green_pos = info->u.vesa_lfb.green_pos;
+               screen_info->blue_size = info->u.vesa_lfb.blue_size;
+               screen_info->blue_pos = info->u.vesa_lfb.blue_pos;
+               screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size;
+               screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos;
+               if (size >= offsetof(struct dom0_vga_console_info,
+                                    u.vesa_lfb.gbl_caps)
+                   + sizeof(info->u.vesa_lfb.gbl_caps))
+                       screen_info->capabilities = info->u.vesa_lfb.gbl_caps;
+               if (size >= offsetof(struct dom0_vga_console_info,
+                                    u.vesa_lfb.mode_attrs)
+                   + sizeof(info->u.vesa_lfb.mode_attrs))
+                       screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs;
+               break;
+       }
+}
index 7367ed44a07ba58c5cbe7d6855111864df33ee67..8223cd234f81f920d6ee602793533e3c9a53cc0e 100644 (file)
@@ -88,10 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu)
 }
 #endif
 
-void __init xen_init_apic(void);
+struct dom0_vga_console_info;
+
+#ifdef CONFIG_XEN_DOM0
+void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
+#else
+static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
+                                      size_t size)
 {
 }
-static inline void __init xen_init_apic(void)
+#endif
+
 /* Declare an asm function, along with symbols needed to make it
    inlineable */
 #define DECL_ASM(ret, name, ...)               \
index dd8de7b124ee85dd35b0495db18c85465a03df45..ed5bc1acb583640e7e8a2014270d2c4527d96c89 100644 (file)
@@ -466,6 +466,45 @@ struct start_info {
        int8_t cmd_line[MAX_GUEST_CMDLINE];
 };
 
+struct dom0_vga_console_info {
+       uint8_t video_type;
+#define XEN_VGATYPE_TEXT_MODE_3 0x03
+#define XEN_VGATYPE_VESA_LFB    0x23
+
+       union {
+               struct {
+                       /* Font height, in pixels. */
+                       uint16_t font_height;
+                       /* Cursor location (column, row). */
+                       uint16_t cursor_x, cursor_y;
+                       /* Number of rows and columns (dimensions in characters). */
+                       uint16_t rows, columns;
+               } text_mode_3;
+
+               struct {
+                       /* Width and height, in pixels. */
+                       uint16_t width, height;
+                       /* Bytes per scan line. */
+                       uint16_t bytes_per_line;
+                       /* Bits per pixel. */
+                       uint16_t bits_per_pixel;
+                       /* LFB physical address, and size (in units of 64kB). */
+                       uint32_t lfb_base;
+                       uint32_t lfb_size;
+                       /* RGB mask offsets and sizes, as defined by VBE 1.2+ */
+                       uint8_t  red_pos, red_size;
+                       uint8_t  green_pos, green_size;
+                       uint8_t  blue_pos, blue_size;
+                       uint8_t  rsvd_pos, rsvd_size;
+
+                       /* VESA capabilities (offset 0xa, VESA command 0x4f00). */
+                       uint32_t gbl_caps;
+                       /* Mode attributes (offset 0x0, VESA command 0x4f01). */
+                       uint16_t mode_attrs;
+               } vesa_lfb;
+       } u;
+};
+
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
 #define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */