Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7fdd84e authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk
Browse files

Merge branch 'stable/vga.support' into stable/drivers

* stable/vga.support:
  xen: allow enable use of VGA console on dom0
parents 03dc6107 c2419b4a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \
obj-$(CONFIG_SMP)		+= smp.o
obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o

obj-$(CONFIG_XEN_DOM0)		+= vga.o
obj-$(CONFIG_SWIOTLB_XEN)	+= pci-swiotlb-xen.o
+8 −0
Original line number Diff line number Diff line
@@ -1248,6 +1248,14 @@ asmlinkage void __init xen_start_kernel(void)
		if (pci_xen)
			x86_init.pci.arch_init = pci_xen_init;
	} else {
		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;

		/* Make sure ACS will be enabled */
		pci_request_acs();
	}

arch/x86/xen/vga.c

0 → 100644
+67 −0
Original line number Diff line number Diff line
#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;
	}
}
+11 −0
Original line number Diff line number Diff line
@@ -88,6 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu)
}
#endif

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)
{
}
#endif

/* Declare an asm function, along with symbols needed to make it
   inlineable */
#define DECL_ASM(ret, name, ...)		\
+39 −0
Original line number Diff line number Diff line
@@ -450,6 +450,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? */