xen/edid.patch

196 lines
7.0 KiB
Diff

Index: 2007-05-14/xen/arch/x86/Makefile
===================================================================
--- 2007-05-14.orig/xen/arch/x86/Makefile 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/arch/x86/Makefile 2007-03-19 14:07:50.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-05-14/xen/arch/x86/boot/realmode.S
===================================================================
--- 2007-05-14.orig/xen/arch/x86/boot/realmode.S 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/arch/x86/boot/realmode.S 2007-03-21 14:35:14.000000000 +0100
@@ -142,4 +142,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-05-14/xen/arch/x86/boot/video.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ 2007-05-14/xen/arch/x86/boot/video.S 2007-03-19 14:07: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-05-14/xen/arch/x86/boot/x86_32.S
===================================================================
--- 2007-05-14.orig/xen/arch/x86/boot/x86_32.S 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:50.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-05-14/xen/arch/x86/boot/x86_64.S
===================================================================
--- 2007-05-14.orig/xen/arch/x86/boot/x86_64.S 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:50.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-05-14/xen/arch/x86/platform_hypercall.c
===================================================================
--- 2007-05-14.orig/xen/arch/x86/platform_hypercall.c 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/arch/x86/platform_hypercall.c 2007-07-02 12:09:50.000000000 +0200
@@ -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)
@@ -212,6 +218,27 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
u.firmware_info.u.disk_mbr_signature)
? -EFAULT : 0);
break;
+ case XEN_FW_VBEDDC_INFO:
+ ret = -ESRCH;
+ if ( op->u.firmware_info.index != 0 )
+ break;
+ if ( *(u32 *)ddc.edid == 0x13131313 )
+ break;
+
+ op->u.firmware_info.u.vbeddc_info.capabilities =
+ ddc.capabilities;
+ op->u.firmware_info.u.vbeddc_info.edid_transfer_time =
+ ddc.edid_transfer_time;
+
+ ret = 0;
+ if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
+ u.vbeddc_info.capabilities) ||
+ copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
+ u.vbeddc_info.edid_transfer_time) ||
+ copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid,
+ ddc.edid, ARRAY_SIZE(ddc.edid)) )
+ ret = -EFAULT;
+ break;
default:
ret = -EINVAL;
break;
@@ -231,11 +258,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-05-14/xen/include/public/platform.h
===================================================================
--- 2007-05-14.orig/xen/include/public/platform.h 2007-07-02 12:09:34.000000000 +0200
+++ 2007-05-14/xen/include/public/platform.h 2007-07-02 11:49:06.000000000 +0200
@@ -117,6 +117,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_platform_q
#define XENPF_firmware_info 50
#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;