[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] add hypercall function for retrieving EDD info



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

Index: 2007-06-18/xen/arch/x86/boot/edd.S
===================================================================
--- 2007-06-18.orig/xen/arch/x86/boot/edd.S     2007-06-18 11:10:07.000000000 
+0200
+++ 2007-06-18/xen/arch/x86/boot/edd.S  2007-06-18 11:10:37.000000000 +0200
@@ -16,17 +16,13 @@
  * Updated and ported for Xen by Keir Fraser <keir@xxxxxxxxxxxxx> June 2007
  */
 
+#include <asm/edd.h>
+
         .code16
 
 /* Offset of disc signature in the MBR. */
 #define EDD_MBR_SIG_OFFSET      0x1B8
 
-/* Maximum number of EDD information structures at boot_edd_info. */
-#define EDD_INFO_MAX            6
-
-/* Maximum number of MBR signatures at boot_edd_signature. */
-#define EDD_MBR_SIG_MAX         16
-
 /* Size of components of EDD information structure. */
 #define EDDEXTSIZE              8
 #define EDDPARMSIZE             74
@@ -151,6 +147,7 @@ opt_edd:
         .byte   0                               # edd=on/off/skipmbr
 
 .globl  boot_edd_info_nr, boot_edd_signature_nr
+.globl  boot_edd_info, boot_edd_signature
 boot_edd_info_nr:
         .byte   0
 boot_edd_signature_nr:
Index: 2007-06-18/xen/arch/x86/platform_hypercall.c
===================================================================
--- 2007-06-18.orig/xen/arch/x86/platform_hypercall.c   2007-06-18 
11:10:07.000000000 +0200
+++ 2007-06-18/xen/arch/x86/platform_hypercall.c        2007-06-18 
11:05:17.000000000 +0200
@@ -20,14 +20,28 @@
 #include <xen/guest_access.h>
 #include <asm/current.h>
 #include <public/platform.h>
+#include <asm/edd.h>
 #include <asm/mtrr.h>
 #include "cpu/mtrr/mtrr.h"
 
+struct edd {
+       unsigned int mbr_signature[EDD_MBR_SIG_MAX];
+       struct edd_info edd_info[EDD_INFO_MAX];
+       unsigned char mbr_signature_nr;
+       unsigned char edd_info_nr;
+};
+
 #ifndef COMPAT
 typedef long ret_t;
 DEFINE_SPINLOCK(xenpf_lock);
+struct edd edd;
+# undef copy_from_compat
+# define copy_from_compat copy_from_guest
+# undef copy_to_compat
+# define copy_to_compat copy_to_guest
 #else
 extern spinlock_t xenpf_lock;
+extern struct edd edd;
 #endif
 
 ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
@@ -151,6 +165,73 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
     }
     break;
 
+    case XENPF_firmware_info:
+        switch ( op->u.firmware_info.type )
+        {
+        case XEN_FW_DISK_INFO:
+            if ( op->u.firmware_info.index < edd.edd_info_nr )
+            {
+                const struct edd_info *info = edd.edd_info + 
op->u.firmware_info.index;
+
+                op->u.firmware_info.u.disk_info.max_cylinder      = 
info->legacy_max_cylinder;
+                op->u.firmware_info.u.disk_info.max_head          = 
info->legacy_max_head;
+                op->u.firmware_info.u.disk_info.sectors_per_track = 
info->legacy_sectors_per_track;
+                if ( copy_field_to_guest(u_xenpf_op, op, 
u.firmware_info.u.disk_info) )
+                    ret = -EFAULT;
+            }
+            else
+                ret = -ESRCH;
+            break;
+        case XEN_FW_EDD_INFO:
+            if ( op->u.firmware_info.index < edd.edd_info_nr )
+            {
+                const struct edd_info *info = edd.edd_info + 
op->u.firmware_info.index;
+
+                op->u.firmware_info.u.edd_info.device    = info->device;
+                op->u.firmware_info.u.edd_info.version   = info->version;
+                op->u.firmware_info.u.edd_info.interface = 
info->interface_support;
+                if ( copy_field_to_guest(u_xenpf_op, op, 
u.firmware_info.u.edd_info) )
+                    ret = -EFAULT;
+            }
+            else
+                ret = -ESRCH;
+            break;
+        case XEN_FW_EDD_PARAMS:
+            if ( op->u.firmware_info.index < edd.edd_info_nr )
+            {
+                u16 length;
+
+                if ( copy_from_compat(&length, 
op->u.firmware_info.u.edd_params, 1) == 0 )
+                {
+                    if ( length > 
edd.edd_info[op->u.firmware_info.index].params.length )
+                        length = 
edd.edd_info[op->u.firmware_info.index].params.length;
+                    if ( copy_to_compat(op->u.firmware_info.u.edd_params,
+                                        
(u8*)&edd.edd_info[op->u.firmware_info.index].params,
+                                        length) )
+                        ret = -EFAULT;
+                }
+                else
+                    ret = -EFAULT;
+            }
+            else
+                ret = -ESRCH;
+            break;
+        case XEN_FW_MBR_SIGNATURE:
+            if ( op->u.firmware_info.index < edd.mbr_signature_nr )
+            {
+                op->u.firmware_info.u.mbr_signature = 
edd.mbr_signature[op->u.firmware_info.index];
+                if ( copy_field_to_guest(u_xenpf_op, op, 
u.firmware_info.u.mbr_signature) )
+                    ret = -EFAULT;
+            }
+            else
+                ret = -ESRCH;
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
+
     default:
         ret = -ENOSYS;
         break;
@@ -161,6 +242,19 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
     return ret;
 }
 
+#ifndef COMPAT
+static int __init firmware_init(void)
+{
+    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);
+
+    return 0;
+}
+__initcall(firmware_init);
+#endif
+
 /*
  * Local variables:
  * mode: C
Index: 2007-06-18/xen/include/asm-x86/edd.h
===================================================================
--- 2007-06-18.orig/xen/include/asm-x86/edd.h   2007-06-18 11:10:07.000000000 
+0200
+++ 2007-06-18/xen/include/asm-x86/edd.h        2007-06-18 11:01:50.000000000 
+0200
@@ -23,6 +23,109 @@
 #ifndef __XEN_EDD_H__
 #define __XEN_EDD_H__
 
+#ifndef __ASSEMBLY__
+
+struct edd_device_params {
+       u16 length;
+       u16 info_flags;
+       u32 num_default_cylinders;
+       u32 num_default_heads;
+       u32 sectors_per_track;
+       u64 number_of_sectors;
+       u16 bytes_per_sector;
+       u32 dpte_ptr;           /* 0xFFFFFFFF for our purposes */
+       u16 key;                /* = 0xBEDD */
+       u8 device_path_info_length;     /* = 44 */
+       u8 reserved2;
+       u16 reserved3;
+       u8 host_bus_type[4];
+       u8 interface_type[8];
+       union {
+               struct {
+                       u16 base_address;
+                       u16 reserved1;
+                       u32 reserved2;
+               } __attribute__ ((packed)) isa;
+               struct {
+                       u8 bus;
+                       u8 slot;
+                       u8 function;
+                       u8 channel;
+                       u32 reserved;
+               } __attribute__ ((packed)) pci;
+               /* pcix is same as pci */
+               struct {
+                       u64 reserved;
+               } __attribute__ ((packed)) ibnd;
+               struct {
+                       u64 reserved;
+               } __attribute__ ((packed)) xprs;
+               struct {
+                       u64 reserved;
+               } __attribute__ ((packed)) htpt;
+               struct {
+                       u64 reserved;
+               } __attribute__ ((packed)) unknown;
+       } interface_path;
+       union {
+               struct {
+                       u8 device;
+                       u8 reserved1;
+                       u16 reserved2;
+                       u32 reserved3;
+                       u64 reserved4;
+               } __attribute__ ((packed)) ata;
+               struct {
+                       u8 device;
+                       u8 lun;
+                       u8 reserved1;
+                       u8 reserved2;
+                       u32 reserved3;
+                       u64 reserved4;
+               } __attribute__ ((packed)) atapi;
+               struct {
+                       u16 id;
+                       u64 lun;
+                       u16 reserved1;
+                       u32 reserved2;
+               } __attribute__ ((packed)) scsi;
+               struct {
+                       u64 serial_number;
+                       u64 reserved;
+               } __attribute__ ((packed)) usb;
+               struct {
+                       u64 eui;
+                       u64 reserved;
+               } __attribute__ ((packed)) i1394;
+               struct {
+                       u64 wwid;
+                       u64 lun;
+               } __attribute__ ((packed)) fibre;
+               struct {
+                       u64 identity_tag;
+                       u64 reserved;
+               } __attribute__ ((packed)) i2o;
+               struct {
+                       u32 array_number;
+                       u32 reserved1;
+                       u64 reserved2;
+               } __attribute__ ((packed)) raid;
+               struct {
+                       u8 device;
+                       u8 reserved1;
+                       u16 reserved2;
+                       u32 reserved3;
+                       u64 reserved4;
+               } __attribute__ ((packed)) sata;
+               struct {
+                       u64 reserved1;
+                       u64 reserved2;
+               } __attribute__ ((packed)) unknown;
+       } device_path;
+       u8 reserved4;
+       u8 checksum;
+} __attribute__ ((packed));
+
 struct edd_info {
     /* Int13, Fn48: Check Extensions Present. */
     u8 device;                   /* %dl: device */
@@ -33,12 +136,24 @@ struct edd_info {
     u8 legacy_max_head;          /* %dh: maximum head number */
     u8 legacy_sectors_per_track; /* %cl[5:0]: maximum sector number */
     /* Int13, Fn41: Get Device Parameters */
-    u8 edd_device_params[74];    /* as filled into %ds:%si */
+    struct edd_device_params params; /* as filled into %ds:%si */
 } __attribute__ ((packed));
 
-extern u32 boot_edd_signature[];
+#endif
+
+/* Maximum number of MBR signatures at boot_edd_signature. */
+#define EDD_MBR_SIG_MAX         16
+
+/* Maximum number of EDD information structures at boot_edd_info. */
+#define EDD_INFO_MAX            6
+
+#ifndef __ASSEMBLY__
+
+extern u32 boot_edd_signature[EDD_MBR_SIG_MAX];
 extern u8 boot_edd_signature_nr;
-extern struct edd_info boot_edd_info[];
+extern struct edd_info boot_edd_info[EDD_INFO_MAX];
 extern u8 boot_edd_info_nr;
 
+#endif
+
 #endif /* __XEN_EDD_H__ */
Index: 2007-06-18/xen/include/public/platform.h
===================================================================
--- 2007-06-18.orig/xen/include/public/platform.h       2007-06-18 
11:10:07.000000000 +0200
+++ 2007-06-18/xen/include/public/platform.h    2007-06-18 11:05:17.000000000 
+0200
@@ -114,6 +114,35 @@ struct xenpf_platform_quirk {
 typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
 
+#define XENPF_firmware_info       50
+#define XEN_FW_DISK_INFO          1 /* from int 13 AH=08 */
+#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
+struct xenpf_firmware_info {
+    /* IN variables. */
+    uint32_t type;
+    uint32_t index;
+    /* OUT variables. */
+    union {
+        struct {
+            uint16_t max_cylinder;
+            uint8_t max_head;
+            uint8_t sectors_per_track;
+        } disk_info;
+        struct {
+            uint8_t device;
+            uint8_t version;
+            uint16_t interface;
+        } edd_info;
+        /* first uint16_t of buffer must be set to buffer size */
+        XEN_GUEST_HANDLE(void) edd_params;
+        uint32_t mbr_signature;
+    } u;
+};
+typedef struct xenpf_firmware_info xenpf_firmware_info_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
+
 struct xen_platform_op {
     uint32_t cmd;
     uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -124,6 +153,7 @@ struct xen_platform_op {
         struct xenpf_read_memtype      read_memtype;
         struct xenpf_microcode_update  microcode;
         struct xenpf_platform_quirk    platform_quirk;
+        struct xenpf_firmware_info     firmware_info;
         uint8_t                        pad[128];
     } u;
 };



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.