summaryrefslogtreecommitdiff
blob: cdec9d8d76d87e1335c2aa9e06d8b9508c370d4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# HG changeset 70 patch
# User kfraser@localhost.localdomain
# Date 1182364134 -3600
# Node ID db1ad4e3caf50efd45726d4b6e483869e20a8e51
# Parent  9f2badfda534e764a5c14291909595bbb8af2ee5
Subject: linux/x86: Obtain EDID info from Xen
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>

---
 arch/i386/kernel/setup-xen.c     |    5 ++++-
 arch/x86_64/kernel/setup-xen.c   |    2 +-
 drivers/xen/core/firmware.c      |   19 +++++++++++++++++++
 include/xen/firmware.h           |    2 ++
 include/xen/interface/platform.h |   12 ++++++++++--
 5 files changed, 36 insertions(+), 4 deletions(-)

--- a/arch/i386/kernel/setup-xen.c	2007-08-27 14:01:25.000000000 -0400
+++ b/arch/i386/kernel/setup-xen.c	2007-08-27 14:02:03.000000000 -0400
@@ -156,6 +156,9 @@ struct sys_desc_table_struct {
 };
 struct edid_info edid_info;
 EXPORT_SYMBOL_GPL(edid_info);
+#ifndef CONFIG_XEN
+#define copy_edid() (edid_info = EDID_INFO)
+#endif
 struct ist_info ist_info;
 #if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
 	defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
@@ -1623,7 +1626,7 @@ void __init setup_arch(char **cmdline_p)
 	ROOT_DEV = MKDEV(UNNAMED_MAJOR,0);
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
-	edid_info = EDID_INFO;
+	copy_edid();
 	apm_info.bios = APM_BIOS_INFO;
 	ist_info = IST_INFO;
 	saved_videomode = VIDEO_MODE;
--- a/arch/x86_64/kernel/setup-xen.c	2007-08-27 14:01:25.000000000 -0400
+++ b/arch/x86_64/kernel/setup-xen.c	2007-08-27 14:02:03.000000000 -0400
@@ -616,7 +616,7 @@ void __init setup_arch(char **cmdline_p)
 	} else
 		screen_info.orig_video_isVGA = 0;
 
-	edid_info = EDID_INFO;
+	copy_edid();
 	saved_video_mode = SAVED_VIDEO_MODE;
 	bootloader_type = LOADER_TYPE;
 
--- a/drivers/xen/core/firmware.c	2007-08-27 14:01:25.000000000 -0400
+++ b/drivers/xen/core/firmware.c	2007-08-27 14:01:25.000000000 -0400
@@ -2,6 +2,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/edd.h>
+#include <video/edid.h>
 #include <xen/interface/platform.h>
 #include <asm/hypervisor.h>
 
@@ -53,3 +54,21 @@ void __init copy_edd(void)
 	}
 }
 #endif
+
+void __init copy_edid(void)
+{
+#if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
+	struct xen_platform_op op;
+
+	if (!is_initial_xendomain())
+		return;
+
+	op.cmd = XENPF_firmware_info;
+	op.u.firmware_info.index = 0;
+	op.u.firmware_info.type = XEN_FW_VBEDDC_INFO;
+	set_xen_guest_handle(op.u.firmware_info.u.vbeddc_info.edid,
+			     edid_info.dummy);
+	if (HYPERVISOR_platform_op(&op) != 0)
+		memset(edid_info.dummy, 0x13, sizeof(edid_info.dummy));
+#endif
+}
--- a/include/xen/firmware.h	2007-08-27 14:01:25.000000000 -0400
+++ b/include/xen/firmware.h	2007-08-27 14:01:25.000000000 -0400
@@ -5,4 +5,6 @@
 void copy_edd(void);
 #endif
 
+void copy_edid(void);
+
 #endif /* __XEN_FIRMWARE_H__ */
--- a/include/xen/interface/platform.h	2007-08-27 14:01:25.000000000 -0400
+++ b/include/xen/interface/platform.h	2007-08-27 14:01:25.000000000 -0400
@@ -115,8 +115,9 @@ typedef struct xenpf_platform_quirk xenp
 DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
 
 #define XENPF_firmware_info       50
-#define XEN_FW_DISK_INFO          1
-#define XEN_FW_DISK_MBR_SIGNATURE 2
+#define XEN_FW_DISK_INFO          1 /* from int 13 AH=08/41/48 */
+#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
+#define XEN_FW_VBEDDC_INFO        3 /* from int 10 AX=4f15 */
 struct xenpf_firmware_info {
     /* IN variables. */
     uint32_t type;
@@ -140,6 +141,13 @@ struct xenpf_firmware_info {
             uint8_t device;                   /* bios device number  */
             uint32_t mbr_signature;           /* offset 0x1b8 in mbr */
         } disk_mbr_signature; /* XEN_FW_DISK_MBR_SIGNATURE */
+        struct {
+            /* Int10, AX=4F15: Get EDID info. */
+            uint8_t capabilities;
+            uint8_t edid_transfer_time;
+            /* must refer to 128-byte buffer */
+            XEN_GUEST_HANDLE(uint8_t) edid;
+        } vbeddc_info; /* XEN_FW_VBEDDC_INFO */
     } u;
 };
 typedef struct xenpf_firmware_info xenpf_firmware_info_t;