Jan Beulich
2007-Jun-19 09:51 UTC
[Xen-devel] [PATCH] add hypercall function for retrieving EDID info
Note that this depends on the prior submissions adjusting guest copy and retrieving EDD info. Signed-off-by: Jan Beulich <jbeulich@novell.com> Index: 2007-06-18/xen/arch/x86/platform_hypercall.c ==================================================================--- 2007-06-18.orig/xen/arch/x86/platform_hypercall.c 2007-06-18 11:05:17.000000000 +0200 +++ 2007-06-18/xen/arch/x86/platform_hypercall.c 2007-06-18 17:46:20.000000000 +0200 @@ -31,10 +31,15 @@ struct edd { unsigned char edd_info_nr; }; +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 @@ -42,6 +47,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) @@ -226,6 +232,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; @@ -245,11 +266,21 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe #ifndef COMPAT static int __init firmware_init(void) { + extern uint16_t boot_edid_caps; + extern uint8_t boot_edid_info[]; + memcpy(edd.mbr_signature, bootsym(boot_edd_signature), sizeof(edd.mbr_signature)); memcpy(edd.edd_info, bootsym(boot_edd_info), sizeof(edd.edd_info)); edd.mbr_signature_nr = bootsym(boot_edd_signature_nr); edd.edd_info_nr = bootsym(boot_edd_info_nr); + if ( bootsym(boot_edid_caps) != 0x1313 ) + { + ddc.capabilities = bootsym(boot_edid_caps); + ddc.edid_transfer_time = bootsym(boot_edid_caps) >> 8; + memcpy(ddc.edid, bootsym(boot_edid_info), sizeof(ddc.edid)); + } + return 0; } __initcall(firmware_init); Index: 2007-06-18/xen/include/public/platform.h ==================================================================--- 2007-06-18.orig/xen/include/public/platform.h 2007-06-18 11:05:17.000000000 +0200 +++ 2007-06-18/xen/include/public/platform.h 2007-06-18 10:39:22.000000000 +0200 @@ -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; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel