diff options
-rw-r--r-- | arch/x86/xen/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 8 | ||||
-rw-r--r-- | arch/x86/xen/vga.c | 67 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 11 | ||||
-rw-r--r-- | include/xen/interface/xen.h | 39 |
5 files changed, 126 insertions, 1 deletions
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 17c565de3d64..a6575b949b11 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -18,5 +18,5 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ | |||
18 | obj-$(CONFIG_SMP) += smp.o | 18 | obj-$(CONFIG_SMP) += smp.o |
19 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o | 19 | obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o |
20 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | 20 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
21 | 21 | obj-$(CONFIG_XEN_DOM0) += vga.o | |
22 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o | 22 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e3c6a06cf725..4abd2d5d04f7 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1241,6 +1241,14 @@ asmlinkage void __init xen_start_kernel(void) | |||
1241 | if (pci_xen) | 1241 | if (pci_xen) |
1242 | x86_init.pci.arch_init = pci_xen_init; | 1242 | x86_init.pci.arch_init = pci_xen_init; |
1243 | } else { | 1243 | } else { |
1244 | const struct dom0_vga_console_info *info = | ||
1245 | (void *)((char *)xen_start_info + | ||
1246 | xen_start_info->console.dom0.info_off); | ||
1247 | |||
1248 | xen_init_vga(info, xen_start_info->console.dom0.info_size); | ||
1249 | xen_start_info->console.domU.mfn = 0; | ||
1250 | xen_start_info->console.domU.evtchn = 0; | ||
1251 | |||
1244 | /* Make sure ACS will be enabled */ | 1252 | /* Make sure ACS will be enabled */ |
1245 | pci_request_acs(); | 1253 | pci_request_acs(); |
1246 | } | 1254 | } |
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c new file mode 100644 index 000000000000..1cd7f4d11e29 --- /dev/null +++ b/arch/x86/xen/vga.c | |||
@@ -0,0 +1,67 @@ | |||
1 | #include <linux/screen_info.h> | ||
2 | #include <linux/init.h> | ||
3 | |||
4 | #include <asm/bootparam.h> | ||
5 | #include <asm/setup.h> | ||
6 | |||
7 | #include <xen/interface/xen.h> | ||
8 | |||
9 | #include "xen-ops.h" | ||
10 | |||
11 | void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size) | ||
12 | { | ||
13 | struct screen_info *screen_info = &boot_params.screen_info; | ||
14 | |||
15 | /* This is drawn from a dump from vgacon:startup in | ||
16 | * standard Linux. */ | ||
17 | screen_info->orig_video_mode = 3; | ||
18 | screen_info->orig_video_isVGA = 1; | ||
19 | screen_info->orig_video_lines = 25; | ||
20 | screen_info->orig_video_cols = 80; | ||
21 | screen_info->orig_video_ega_bx = 3; | ||
22 | screen_info->orig_video_points = 16; | ||
23 | screen_info->orig_y = screen_info->orig_video_lines - 1; | ||
24 | |||
25 | switch (info->video_type) { | ||
26 | case XEN_VGATYPE_TEXT_MODE_3: | ||
27 | if (size < offsetof(struct dom0_vga_console_info, u.text_mode_3) | ||
28 | + sizeof(info->u.text_mode_3)) | ||
29 | break; | ||
30 | screen_info->orig_video_lines = info->u.text_mode_3.rows; | ||
31 | screen_info->orig_video_cols = info->u.text_mode_3.columns; | ||
32 | screen_info->orig_x = info->u.text_mode_3.cursor_x; | ||
33 | screen_info->orig_y = info->u.text_mode_3.cursor_y; | ||
34 | screen_info->orig_video_points = | ||
35 | info->u.text_mode_3.font_height; | ||
36 | break; | ||
37 | |||
38 | case XEN_VGATYPE_VESA_LFB: | ||
39 | if (size < offsetof(struct dom0_vga_console_info, | ||
40 | u.vesa_lfb.gbl_caps)) | ||
41 | break; | ||
42 | screen_info->orig_video_isVGA = VIDEO_TYPE_VLFB; | ||
43 | screen_info->lfb_width = info->u.vesa_lfb.width; | ||
44 | screen_info->lfb_height = info->u.vesa_lfb.height; | ||
45 | screen_info->lfb_depth = info->u.vesa_lfb.bits_per_pixel; | ||
46 | screen_info->lfb_base = info->u.vesa_lfb.lfb_base; | ||
47 | screen_info->lfb_size = info->u.vesa_lfb.lfb_size; | ||
48 | screen_info->lfb_linelength = info->u.vesa_lfb.bytes_per_line; | ||
49 | screen_info->red_size = info->u.vesa_lfb.red_size; | ||
50 | screen_info->red_pos = info->u.vesa_lfb.red_pos; | ||
51 | screen_info->green_size = info->u.vesa_lfb.green_size; | ||
52 | screen_info->green_pos = info->u.vesa_lfb.green_pos; | ||
53 | screen_info->blue_size = info->u.vesa_lfb.blue_size; | ||
54 | screen_info->blue_pos = info->u.vesa_lfb.blue_pos; | ||
55 | screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; | ||
56 | screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; | ||
57 | if (size >= offsetof(struct dom0_vga_console_info, | ||
58 | u.vesa_lfb.gbl_caps) | ||
59 | + sizeof(info->u.vesa_lfb.gbl_caps)) | ||
60 | screen_info->capabilities = info->u.vesa_lfb.gbl_caps; | ||
61 | if (size >= offsetof(struct dom0_vga_console_info, | ||
62 | u.vesa_lfb.mode_attrs) | ||
63 | + sizeof(info->u.vesa_lfb.mode_attrs)) | ||
64 | screen_info->vesa_attributes = info->u.vesa_lfb.mode_attrs; | ||
65 | break; | ||
66 | } | ||
67 | } | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 3112f55638c4..e14c54eff23d 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -88,6 +88,17 @@ static inline void xen_uninit_lock_cpu(int cpu) | |||
88 | } | 88 | } |
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | struct dom0_vga_console_info; | ||
92 | |||
93 | #ifdef CONFIG_XEN_DOM0 | ||
94 | void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size); | ||
95 | #else | ||
96 | static inline void __init xen_init_vga(const struct dom0_vga_console_info *info, | ||
97 | size_t size) | ||
98 | { | ||
99 | } | ||
100 | #endif | ||
101 | |||
91 | /* Declare an asm function, along with symbols needed to make it | 102 | /* Declare an asm function, along with symbols needed to make it |
92 | inlineable */ | 103 | inlineable */ |
93 | #define DECL_ASM(ret, name, ...) \ | 104 | #define DECL_ASM(ret, name, ...) \ |
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index b33257bc7e83..29b362eab6cc 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h | |||
@@ -449,6 +449,45 @@ struct start_info { | |||
449 | int8_t cmd_line[MAX_GUEST_CMDLINE]; | 449 | int8_t cmd_line[MAX_GUEST_CMDLINE]; |
450 | }; | 450 | }; |
451 | 451 | ||
452 | struct dom0_vga_console_info { | ||
453 | uint8_t video_type; | ||
454 | #define XEN_VGATYPE_TEXT_MODE_3 0x03 | ||
455 | #define XEN_VGATYPE_VESA_LFB 0x23 | ||
456 | |||
457 | union { | ||
458 | struct { | ||
459 | /* Font height, in pixels. */ | ||
460 | uint16_t font_height; | ||
461 | /* Cursor location (column, row). */ | ||
462 | uint16_t cursor_x, cursor_y; | ||
463 | /* Number of rows and columns (dimensions in characters). */ | ||
464 | uint16_t rows, columns; | ||
465 | } text_mode_3; | ||
466 | |||
467 | struct { | ||
468 | /* Width and height, in pixels. */ | ||
469 | uint16_t width, height; | ||
470 | /* Bytes per scan line. */ | ||
471 | uint16_t bytes_per_line; | ||
472 | /* Bits per pixel. */ | ||
473 | uint16_t bits_per_pixel; | ||
474 | /* LFB physical address, and size (in units of 64kB). */ | ||
475 | uint32_t lfb_base; | ||
476 | uint32_t lfb_size; | ||
477 | /* RGB mask offsets and sizes, as defined by VBE 1.2+ */ | ||
478 | uint8_t red_pos, red_size; | ||
479 | uint8_t green_pos, green_size; | ||
480 | uint8_t blue_pos, blue_size; | ||
481 | uint8_t rsvd_pos, rsvd_size; | ||
482 | |||
483 | /* VESA capabilities (offset 0xa, VESA command 0x4f00). */ | ||
484 | uint32_t gbl_caps; | ||
485 | /* Mode attributes (offset 0x0, VESA command 0x4f01). */ | ||
486 | uint16_t mode_attrs; | ||
487 | } vesa_lfb; | ||
488 | } u; | ||
489 | }; | ||
490 | |||
452 | /* These flags are passed in the 'flags' field of start_info_t. */ | 491 | /* These flags are passed in the 'flags' field of start_info_t. */ |
453 | #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ | 492 | #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ |
454 | #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ | 493 | #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ |