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

[Xen-changelog] [xen-unstable] x86: Add hypercall function for retrieving EDD info.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1182361384 -3600
# Node ID 296fd2598e003029c6f44b2058522b0e9ac55646
# Parent  7825043607bc453dc4657f3bf8b53baeb425dc44
x86: Add hypercall function for retrieving EDD info.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/boot/edd.S           |   24 ++++++------
 xen/arch/x86/platform_hypercall.c |   72 ++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/setup.c              |    2 -
 xen/include/asm-x86/edd.h         |   18 +++++++--
 xen/include/public/platform.h     |   32 ++++++++++++++++
 5 files changed, 131 insertions(+), 17 deletions(-)

diff -r 7825043607bc -r 296fd2598e00 xen/arch/x86/boot/edd.S
--- a/xen/arch/x86/boot/edd.S   Wed Jun 20 17:07:15 2007 +0100
+++ b/xen/arch/x86/boot/edd.S   Wed Jun 20 18:43:04 2007 +0100
@@ -24,7 +24,7 @@
 /* Maximum number of EDD information structures at boot_edd_info. */
 #define EDD_INFO_MAX            6
 
-/* Maximum number of MBR signatures at boot_edd_signature. */
+/* Maximum number of MBR signatures at boot_mbr_signature. */
 #define EDD_MBR_SIG_MAX         16
 
 /* Size of components of EDD information structure. */
@@ -40,10 +40,8 @@ get_edd:
 # Read the first sector of each BIOS disk device and store the 4-byte signature
 edd_mbr_sig_start:
         movb    $0x80, %dl                      # from device 80
-        movw    $bootsym(boot_edd_signature),%bx # store buffer ptr in bx
+        movw    $bootsym(boot_mbr_signature),%bx # store buffer ptr in bx
 edd_mbr_sig_read:
-        movl    $0xFFFFFFFF, %eax
-        movl    %eax, (%bx)                     # assume failure
         pushw   %bx
         movb    $0x02, %ah                      # 0x02 Read Sectors
         movb    $1, %al                         # read 1 sector
@@ -64,11 +62,12 @@ edd_mbr_sig_read:
         cmpb    $0, %ah                         # some BIOSes do not set CF
         jne     edd_mbr_sig_done                # on failure, we're done.
         movl    bootsym(boot_edd_info)+EDD_MBR_SIG_OFFSET,%eax
-        movl    %eax, (%bx)                     # store signature from MBR
-        incb    bootsym(boot_edd_signature_nr)  # note that we stored something
+        movb    %dl, (%bx)                      # store BIOS drive number
+        movl    %eax, 4(%bx)                    # store signature from MBR
+        incb    bootsym(boot_mbr_signature_nr)  # note that we stored something
         incb    %dl                             # increment to next device
-        addw    $4, %bx                         # increment sig buffer ptr
-        cmpb    $EDD_MBR_SIG_MAX,bootsym(boot_edd_signature_nr)
+        addw    $8, %bx                         # increment sig buffer ptr
+        cmpb    $EDD_MBR_SIG_MAX,bootsym(boot_mbr_signature_nr)
         jb      edd_mbr_sig_read
 edd_mbr_sig_done:
 
@@ -150,12 +149,13 @@ opt_edd:
 opt_edd:
         .byte   0                               # edd=on/off/skipmbr
 
-.globl  boot_edd_info_nr, boot_edd_signature_nr
+.globl  boot_edd_info, boot_edd_info_nr
+.globl  boot_mbr_signature, boot_mbr_signature_nr
 boot_edd_info_nr:
         .byte   0
-boot_edd_signature_nr:
+boot_mbr_signature_nr:
         .byte   0
-boot_edd_signature:
-        .fill   EDD_MBR_SIG_MAX*4,1,0
+boot_mbr_signature:
+        .fill   EDD_MBR_SIG_MAX*8,1,0
 boot_edd_info:
         .fill   512,1,0                         # big enough for a disc sector
diff -r 7825043607bc -r 296fd2598e00 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Wed Jun 20 17:07:15 2007 +0100
+++ b/xen/arch/x86/platform_hypercall.c Wed Jun 20 18:43:04 2007 +0100
@@ -20,12 +20,17 @@
 #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"
 
 #ifndef COMPAT
 typedef long ret_t;
 DEFINE_SPINLOCK(xenpf_lock);
+# 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;
 #endif
@@ -150,6 +155,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: {
+            const struct edd_info *info;
+            u16 length;
+
+            ret = -ESRCH;
+            if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) )
+                break;
+
+            info = bootsym(boot_edd_info) + op->u.firmware_info.index;
+
+            /* Transfer the EDD info block. */
+            ret = -EFAULT;
+            if ( copy_from_compat(&length, op->u.firmware_info.u.
+                                  disk_info.edd_params, 1) )
+                break;
+            if ( length > info->edd_device_params.length )
+                length = info->edd_device_params.length;
+            if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
+                                (u8 *)&info->edd_device_params,
+                                length) )
+                break;
+            if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
+                                &length, 1) )
+                break;
+
+            /* Transfer miscellaneous other information values. */
+#define C(x) op->u.firmware_info.u.disk_info.x = info->x;
+            C(device);
+            C(version);
+            C(interface_support);
+            C(legacy_max_cylinder);
+            C(legacy_max_head);
+            C(legacy_sectors_per_track);
+#undef C
+
+            ret = (copy_field_to_guest(u_xenpf_op, op,
+                                      u.firmware_info.u.disk_info)
+                   ? -EFAULT : 0);
+            break;
+        }
+        case XEN_FW_DISK_MBR_SIGNATURE: {
+            const struct mbr_signature *sig;
+
+            ret = -ESRCH;
+            if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) )
+                break;
+
+            sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index;
+
+            op->u.firmware_info.u.disk_mbr_signature.device = sig->device;
+            op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
+                sig->signature;
+
+            ret = (copy_field_to_guest(u_xenpf_op, op,
+                                      u.firmware_info.u.disk_mbr_signature)
+                   ? -EFAULT : 0);
+            break;
+        }
+        default:
+            ret = -EINVAL;
+            break;
+        }
+        break;
 
     default:
         ret = -ENOSYS;
diff -r 7825043607bc -r 296fd2598e00 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Wed Jun 20 17:07:15 2007 +0100
+++ b/xen/arch/x86/setup.c      Wed Jun 20 18:43:04 2007 +0100
@@ -505,7 +505,7 @@ void __init __start_xen(unsigned long mb
 
     printk("Disc information:\n");
     printk(" Found %d MBR signatures\n",
-           bootsym(boot_edd_signature_nr));
+           bootsym(boot_mbr_signature_nr));
     printk(" Found %d EDD information structures\n",
            bootsym(boot_edd_info_nr));
 
diff -r 7825043607bc -r 296fd2598e00 xen/include/asm-x86/edd.h
--- a/xen/include/asm-x86/edd.h Wed Jun 20 17:07:15 2007 +0100
+++ b/xen/include/asm-x86/edd.h Wed Jun 20 18:43:04 2007 +0100
@@ -32,12 +32,22 @@ struct edd_info {
     u16 legacy_max_cylinder;     /* %cl[7:6]:%ch: maximum cylinder number */
     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 */
+    /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
+    struct {
+        u16 length;
+        u8 data[72];
+    } edd_device_params;
 } __attribute__ ((packed));
 
-extern u32 boot_edd_signature[];
-extern u8 boot_edd_signature_nr;
+struct mbr_signature {
+    u8 device;
+    u8 pad[3];
+    u32 signature;
+} __attribute__ ((packed));
+
+/* These all reside in the boot trampoline. Access via bootsym(). */
+extern struct mbr_signature boot_mbr_signature[];
+extern u8 boot_mbr_signature_nr;
 extern struct edd_info boot_edd_info[];
 extern u8 boot_edd_info_nr;
 
diff -r 7825043607bc -r 296fd2598e00 xen/include/public/platform.h
--- a/xen/include/public/platform.h     Wed Jun 20 17:07:15 2007 +0100
+++ b/xen/include/public/platform.h     Wed Jun 20 18:43:04 2007 +0100
@@ -114,6 +114,37 @@ typedef struct xenpf_platform_quirk xenp
 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
+#define XEN_FW_DISK_MBR_SIGNATURE 2
+struct xenpf_firmware_info {
+    /* IN variables. */
+    uint32_t type;
+    uint32_t index;
+    /* OUT variables. */
+    union {
+        struct {
+            /* Int13, Fn48: Check Extensions Present. */
+            uint8_t device;                   /* %dl: bios device number */
+            uint8_t version;                  /* %ah: major version      */
+            uint16_t interface_support;       /* %cx: support bitmap     */
+            /* Int13, Fn08: Legacy Get Device Parameters. */
+            uint16_t legacy_max_cylinder;     /* %cl[7:6]:%ch: max cyl # */
+            uint8_t legacy_max_head;          /* %dh: max head #         */
+            uint8_t legacy_sectors_per_track; /* %cl[5:0]: max sector #  */
+            /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
+            /* NB. First uint16_t of buffer must be set to buffer size.      */
+            XEN_GUEST_HANDLE(void) edd_params;
+        } disk_info; /* XEN_FW_DISK_INFO */
+        struct {
+            uint8_t device;                   /* bios device number  */
+            uint32_t mbr_signature;           /* offset 0x1b8 in mbr */
+        } disk_mbr_signature; /* XEN_FW_DISK_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 +155,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-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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