Index: 2007-03-19/xen/arch/x86/Makefile =================================================================== --- 2007-03-19.orig/xen/arch/x86/Makefile 2007-03-19 14:07:47.000000000 +0100 +++ 2007-03-19/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-03-19/xen/arch/x86/boot/realmode.S =================================================================== --- 2007-03-19.orig/xen/arch/x86/boot/realmode.S 2007-03-21 14:35:06.000000000 +0100 +++ 2007-03-19/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-03-19/xen/arch/x86/boot/video.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2007-03-19/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-03-19/xen/arch/x86/boot/x86_32.S =================================================================== --- 2007-03-19.orig/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:47.000000000 +0100 +++ 2007-03-19/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-03-19/xen/arch/x86/boot/x86_64.S =================================================================== --- 2007-03-19.orig/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:47.000000000 +0100 +++ 2007-03-19/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-03-19/xen/arch/x86/platform_hypercall.c =================================================================== --- 2007-03-19.orig/xen/arch/x86/platform_hypercall.c 2007-03-19 14:07:47.000000000 +0100 +++ 2007-03-19/xen/arch/x86/platform_hypercall.c 2007-03-19 14:07:50.000000000 +0100 @@ -24,10 +24,15 @@ #include #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, + 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-03-19/xen/include/public/platform.h =================================================================== --- 2007-03-19.orig/xen/include/public/platform.h 2007-03-19 14:07:47.000000000 +0100 +++ 2007-03-19/xen/include/public/platform.h 2007-03-19 14:07:50.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;