WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 3/3] x86: real mode support: get EDID info

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 3/3] x86: real mode support: get EDID info
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Fri, 02 Mar 2007 10:32:36 +0000
Delivery-date: Fri, 02 Mar 2007 02:31:58 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Obtain EDID info from BIOS and pass it up to Dom0.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: 2007-02-27/xen/arch/x86/Makefile
===================================================================
--- 2007-02-27.orig/xen/arch/x86/Makefile       2007-02-22 15:57:24.000000000 
+0100
+++ 2007-02-27/xen/arch/x86/Makefile    2007-02-22 15:48:44.000000000 +0100
@@ -78,7 +78,7 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H
 boot/mkelf32: boot/mkelf32.c
        $(HOSTCC) $(HOSTCFLAGS) -o $@ $<
 
-boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S
+boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S boot/video.S
 
 .PHONY: clean
 clean::
Index: 2007-02-27/xen/arch/x86/boot/realmode.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/boot/realmode.S        2007-02-22 
15:58:16.000000000 +0100
+++ 2007-02-27/xen/arch/x86/boot/realmode.S     2007-02-22 16:22:31.000000000 
+0100
@@ -140,4 +140,11 @@ eddbuf:                    .skip EDDMAXNR * (EDDEXTSIZE +
 edd_mbr_sig_buf:       .skip EDD_MBR_SIG_MAX * 4
 eddnr:                 .skip 1
 edd_mbr_sig_nr_buf:    .skip 1
+
+       .globl ddc_capabilities, edid_transfer_time, edid
+ddc_capabilities:      .skip 1
+edid_transfer_time:    .skip 1
+edid:                  .skip 128
        .previous
+
+#include "video.S"
Index: 2007-02-27/xen/arch/x86/boot/video.S
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ 2007-02-27/xen/arch/x86/boot/video.S        2007-02-22 16:26:50.000000000 
+0100
@@ -0,0 +1,35 @@
+store_edid:
+       movl    $0x13131313, %eax               # memset block with 0x13
+       movw    $32, %cx
+       movw    $SYM_REAL(edid), %di
+       cld
+       rep
+       stosl
+
+       pushw   %es                             # save ES
+       xorw    %di, %di                        # Report Capability
+       movw    %di, %es                        # ES:DI must be 0:0
+       movw    $0x4f15, %ax
+       xorw    %bx, %bx
+       xorw    %cx, %cx
+       int     $0x10
+       popw    %es                             # restore ES
+
+       testb   %ah, %ah                        # call successful
+       jnz     no_edid
+
+       cmpb    $0x4f, %al                      # function supported
+       jne     no_edid
+
+       movb    %bl, SYM_REAL(ddc_capabilities)
+       movb    %bh, SYM_REAL(edid_transfer_time)
+
+       movw    $0x4f15, %ax                    # do VBE/DDC
+       movw    $0x01, %bx
+       xorw    %cx, %cx
+       xorw    %dx, %dx
+       movw    $SYM_REAL(edid), %di
+       int     $0x10
+
+no_edid:
+       ret
Index: 2007-02-27/xen/arch/x86/boot/x86_32.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/boot/x86_32.S  2007-02-21 18:08:44.000000000 
+0100
+++ 2007-02-27/xen/arch/x86/boot/x86_32.S       2007-02-22 16:28:03.000000000 
+0100
@@ -92,6 +92,8 @@ __start:
 
         pushl   $SYM_PHYS(edd)
         call    realmode
+        pushl   $SYM_PHYS(store_edid)
+        call    realmode
 
 #ifdef CONFIG_X86_PAE
         /* Initialize low and high mappings of all memory with 2MB pages */
Index: 2007-02-27/xen/arch/x86/boot/x86_64.S
===================================================================
--- 2007-02-27.orig/xen/arch/x86/boot/x86_64.S  2007-02-21 17:55:02.000000000 
+0100
+++ 2007-02-27/xen/arch/x86/boot/x86_64.S       2007-02-22 16:28:11.000000000 
+0100
@@ -75,6 +75,8 @@ __start:
         lss     SYM_PHYS(.Lstack_start),%esp
         pushl   $SYM_PHYS(edd)
         call    realmode
+        pushl   $SYM_PHYS(store_edid)
+        call    realmode
 
         /* We begin by interrogating the CPU for the presence of long mode. */
         mov     $0x80000000,%eax
Index: 2007-02-27/xen/arch/x86/platform_hypercall.c
===================================================================
--- 2007-02-27.orig/xen/arch/x86/platform_hypercall.c   2007-02-22 
16:14:39.000000000 +0100
+++ 2007-02-27/xen/arch/x86/platform_hypercall.c        2007-02-22 
16:22:49.000000000 +0100
@@ -24,10 +24,15 @@
 #include <asm/mtrr.h>
 #include "cpu/mtrr/mtrr.h"
 
+struct ddc {
+    uint8_t capabilities, edid_transfer_time, edid[128];
+};
+
 #ifndef COMPAT
 typedef long ret_t;
 DEFINE_SPINLOCK(xenpf_lock);
 struct edd edd;
+struct ddc ddc;
 # undef copy_from_compat
 # define copy_from_compat copy_from_guest
 # undef copy_to_compat
@@ -35,6 +40,7 @@ struct edd edd;
 #else
 extern spinlock_t xenpf_lock;
 extern struct edd edd;
+extern struct ddc ddc;
 #endif
 
 ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
@@ -219,6 +225,21 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
             else
                 ret = -ESRCH;
             break;
+        case XEN_FW_DDC_INFO:
+            if ( op->u.firmware_info.index == 0 )
+            {
+                op->u.firmware_info.u.ddc_info.capabilities       = 
ddc.capabilities;
+                op->u.firmware_info.u.ddc_info.edid_transfer_time = 
ddc.edid_transfer_time;
+                if ( copy_field_to_guest(u_xenpf_op, op, 
u.firmware_info.u.ddc_info.capabilities) ||
+                     copy_field_to_guest(u_xenpf_op, op, 
u.firmware_info.u.ddc_info.edid_transfer_time) ||
+                     copy_to_compat(op->u.firmware_info.u.ddc_info.edid,
+                                    &ddc.edid[0],
+                                    ARRAY_SIZE(ddc.edid)) )
+                    ret = -EFAULT;
+            }
+            else
+                ret = -ESRCH;
+            break;
         default:
             ret = -EINVAL;
             break;
@@ -238,11 +259,17 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
 #ifndef COMPAT
 static int __init firmware_init(void)
 {
+    extern uint8_t ddc_capabilities, edid_transfer_time, edid[];
+
     memcpy(edd.mbr_signature, edd_mbr_sig_buf, sizeof(edd.mbr_signature));
     memcpy(edd.edd_info, eddbuf, sizeof(edd.edd_info));
     edd.mbr_signature_nr = edd_mbr_sig_nr_buf;
     edd.edd_info_nr = eddnr;
 
+    ddc.capabilities = ddc_capabilities;
+    ddc.edid_transfer_time = edid_transfer_time;
+    memcpy(ddc.edid, edid, sizeof(ddc.edid));
+
     return 0;
 }
 __initcall(firmware_init);
Index: 2007-02-27/xen/include/public/platform.h
===================================================================
--- 2007-02-27.orig/xen/include/public/platform.h       2007-02-21 
14:51:00.000000000 +0100
+++ 2007-02-27/xen/include/public/platform.h    2007-02-22 16:10:04.000000000 
+0100
@@ -119,6 +119,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_platform_q
 #define XEN_FW_EDD_INFO           2 /* from int 13 AH=41 */
 #define XEN_FW_EDD_PARAMS         3 /* from int 13 AH=48 */
 #define XEN_FW_MBR_SIGNATURE      4
+#define XEN_FW_DDC_INFO           5 /* from int 10 AX=4f15 */
 struct xenpf_firmware_info {
     /* IN variables. */
     uint32_t type;
@@ -138,6 +139,12 @@ struct xenpf_firmware_info {
         /* first uint16_t of buffer must be set to buffer size */
         XEN_GUEST_HANDLE(void) edd_params;
         uint32_t mbr_signature;
+        struct {
+            uint8_t capabilities;
+            uint8_t edid_transfer_time;
+            /* must refer to 128-byte buffer */
+            XEN_GUEST_HANDLE(uint8_t) edid;
+        } ddc_info;
     } u;
 };
 typedef struct xenpf_firmware_info xenpf_firmware_info_t;
Index: 2007-02-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
===================================================================
--- 2007-02-27.orig/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c   
2007-02-22 16:38:02.000000000 +0100
+++ 2007-02-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c        
2007-02-22 16:43:00.000000000 +0100
@@ -155,6 +155,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)
@@ -1620,7 +1623,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;
Index: 2007-02-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
===================================================================
--- 2007-02-27.orig/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c 
2007-02-22 16:38:02.000000000 +0100
+++ 2007-02-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c      
2007-02-22 16:41:54.000000000 +0100
@@ -613,7 +613,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;
 
Index: 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/firmware.c
===================================================================
--- 2007-02-27.orig/linux-2.6-xen-sparse/drivers/xen/core/firmware.c    
2007-02-22 16:38:02.000000000 +0100
+++ 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/firmware.c 2007-02-22 
16:37:30.000000000 +0100
@@ -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>
 
@@ -59,3 +60,20 @@ void __init copy_edd(void)
        }
 }
 #endif
+
+void __init copy_edid(void)
+{
+#if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
+       xen_platform_op_t op;
+
+       if (!is_initial_xendomain())
+               return;
+
+       op.cmd = XENPF_firmware_info;
+       op.u.firmware_info.index = 0;
+       op.u.firmware_info.type = XEN_FW_DDC_INFO;
+       set_xen_guest_handle(op.u.firmware_info.u.ddc_info.edid, 
edid_info.dummy);
+       if (HYPERVISOR_platform_op(&op) != 0)
+               memset(edid_info.dummy, 0x13, sizeof(edid_info.dummy));
+#endif
+}
Index: 2007-02-27/linux-2.6-xen-sparse/include/xen/firmware.h
===================================================================
--- 2007-02-27.orig/linux-2.6-xen-sparse/include/xen/firmware.h 2007-02-22 
16:38:02.000000000 +0100
+++ 2007-02-27/linux-2.6-xen-sparse/include/xen/firmware.h      2007-02-22 
16:32:13.000000000 +0100
@@ -2,5 +2,6 @@
 #define __XEN_FIRMWARE_H__
 
 void copy_edd(void);
+void copy_edid(void);
 
 #endif /* __XEN_FIRMWARE_H__ */



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH 3/3] x86: real mode support: get EDID info, Jan Beulich <=