direct-io.hg

changeset 15406:296fd2598e00

x86: Add hypercall function for retrieving EDD info.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Jun 20 18:43:04 2007 +0100 (2007-06-20)
parents 7825043607bc
children 6310aebd34a6
files xen/arch/x86/boot/edd.S xen/arch/x86/platform_hypercall.c xen/arch/x86/setup.c xen/include/asm-x86/edd.h xen/include/public/platform.h
line diff
     1.1 --- a/xen/arch/x86/boot/edd.S	Wed Jun 20 17:07:15 2007 +0100
     1.2 +++ b/xen/arch/x86/boot/edd.S	Wed Jun 20 18:43:04 2007 +0100
     1.3 @@ -24,7 +24,7 @@
     1.4  /* Maximum number of EDD information structures at boot_edd_info. */
     1.5  #define EDD_INFO_MAX            6
     1.6  
     1.7 -/* Maximum number of MBR signatures at boot_edd_signature. */
     1.8 +/* Maximum number of MBR signatures at boot_mbr_signature. */
     1.9  #define EDD_MBR_SIG_MAX         16
    1.10  
    1.11  /* Size of components of EDD information structure. */
    1.12 @@ -40,10 +40,8 @@ get_edd:
    1.13  # Read the first sector of each BIOS disk device and store the 4-byte signature
    1.14  edd_mbr_sig_start:
    1.15          movb    $0x80, %dl                      # from device 80
    1.16 -        movw    $bootsym(boot_edd_signature),%bx # store buffer ptr in bx
    1.17 +        movw    $bootsym(boot_mbr_signature),%bx # store buffer ptr in bx
    1.18  edd_mbr_sig_read:
    1.19 -        movl    $0xFFFFFFFF, %eax
    1.20 -        movl    %eax, (%bx)                     # assume failure
    1.21          pushw   %bx
    1.22          movb    $0x02, %ah                      # 0x02 Read Sectors
    1.23          movb    $1, %al                         # read 1 sector
    1.24 @@ -64,11 +62,12 @@ edd_mbr_sig_read:
    1.25          cmpb    $0, %ah                         # some BIOSes do not set CF
    1.26          jne     edd_mbr_sig_done                # on failure, we're done.
    1.27          movl    bootsym(boot_edd_info)+EDD_MBR_SIG_OFFSET,%eax
    1.28 -        movl    %eax, (%bx)                     # store signature from MBR
    1.29 -        incb    bootsym(boot_edd_signature_nr)  # note that we stored something
    1.30 +        movb    %dl, (%bx)                      # store BIOS drive number
    1.31 +        movl    %eax, 4(%bx)                    # store signature from MBR
    1.32 +        incb    bootsym(boot_mbr_signature_nr)  # note that we stored something
    1.33          incb    %dl                             # increment to next device
    1.34 -        addw    $4, %bx                         # increment sig buffer ptr
    1.35 -        cmpb    $EDD_MBR_SIG_MAX,bootsym(boot_edd_signature_nr)
    1.36 +        addw    $8, %bx                         # increment sig buffer ptr
    1.37 +        cmpb    $EDD_MBR_SIG_MAX,bootsym(boot_mbr_signature_nr)
    1.38          jb      edd_mbr_sig_read
    1.39  edd_mbr_sig_done:
    1.40  
    1.41 @@ -150,12 +149,13 @@ edd_done:
    1.42  opt_edd:
    1.43          .byte   0                               # edd=on/off/skipmbr
    1.44  
    1.45 -.globl  boot_edd_info_nr, boot_edd_signature_nr
    1.46 +.globl  boot_edd_info, boot_edd_info_nr
    1.47 +.globl  boot_mbr_signature, boot_mbr_signature_nr
    1.48  boot_edd_info_nr:
    1.49          .byte   0
    1.50 -boot_edd_signature_nr:
    1.51 +boot_mbr_signature_nr:
    1.52          .byte   0
    1.53 -boot_edd_signature:
    1.54 -        .fill   EDD_MBR_SIG_MAX*4,1,0
    1.55 +boot_mbr_signature:
    1.56 +        .fill   EDD_MBR_SIG_MAX*8,1,0
    1.57  boot_edd_info:
    1.58          .fill   512,1,0                         # big enough for a disc sector
     2.1 --- a/xen/arch/x86/platform_hypercall.c	Wed Jun 20 17:07:15 2007 +0100
     2.2 +++ b/xen/arch/x86/platform_hypercall.c	Wed Jun 20 18:43:04 2007 +0100
     2.3 @@ -20,12 +20,17 @@
     2.4  #include <xen/guest_access.h>
     2.5  #include <asm/current.h>
     2.6  #include <public/platform.h>
     2.7 +#include <asm/edd.h>
     2.8  #include <asm/mtrr.h>
     2.9  #include "cpu/mtrr/mtrr.h"
    2.10  
    2.11  #ifndef COMPAT
    2.12  typedef long ret_t;
    2.13  DEFINE_SPINLOCK(xenpf_lock);
    2.14 +# undef copy_from_compat
    2.15 +# define copy_from_compat copy_from_guest
    2.16 +# undef copy_to_compat
    2.17 +# define copy_to_compat copy_to_guest
    2.18  #else
    2.19  extern spinlock_t xenpf_lock;
    2.20  #endif
    2.21 @@ -151,6 +156,73 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
    2.22      }
    2.23      break;
    2.24  
    2.25 +    case XENPF_firmware_info:
    2.26 +        switch ( op->u.firmware_info.type )
    2.27 +        {
    2.28 +        case XEN_FW_DISK_INFO: {
    2.29 +            const struct edd_info *info;
    2.30 +            u16 length;
    2.31 +
    2.32 +            ret = -ESRCH;
    2.33 +            if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) )
    2.34 +                break;
    2.35 +
    2.36 +            info = bootsym(boot_edd_info) + op->u.firmware_info.index;
    2.37 +
    2.38 +            /* Transfer the EDD info block. */
    2.39 +            ret = -EFAULT;
    2.40 +            if ( copy_from_compat(&length, op->u.firmware_info.u.
    2.41 +                                  disk_info.edd_params, 1) )
    2.42 +                break;
    2.43 +            if ( length > info->edd_device_params.length )
    2.44 +                length = info->edd_device_params.length;
    2.45 +            if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
    2.46 +                                (u8 *)&info->edd_device_params,
    2.47 +                                length) )
    2.48 +                break;
    2.49 +            if ( copy_to_compat(op->u.firmware_info.u.disk_info.edd_params,
    2.50 +                                &length, 1) )
    2.51 +                break;
    2.52 +
    2.53 +            /* Transfer miscellaneous other information values. */
    2.54 +#define C(x) op->u.firmware_info.u.disk_info.x = info->x;
    2.55 +            C(device);
    2.56 +            C(version);
    2.57 +            C(interface_support);
    2.58 +            C(legacy_max_cylinder);
    2.59 +            C(legacy_max_head);
    2.60 +            C(legacy_sectors_per_track);
    2.61 +#undef C
    2.62 +
    2.63 +            ret = (copy_field_to_guest(u_xenpf_op, op,
    2.64 +                                      u.firmware_info.u.disk_info)
    2.65 +                   ? -EFAULT : 0);
    2.66 +            break;
    2.67 +        }
    2.68 +        case XEN_FW_DISK_MBR_SIGNATURE: {
    2.69 +            const struct mbr_signature *sig;
    2.70 +
    2.71 +            ret = -ESRCH;
    2.72 +            if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) )
    2.73 +                break;
    2.74 +
    2.75 +            sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index;
    2.76 +
    2.77 +            op->u.firmware_info.u.disk_mbr_signature.device = sig->device;
    2.78 +            op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
    2.79 +                sig->signature;
    2.80 +
    2.81 +            ret = (copy_field_to_guest(u_xenpf_op, op,
    2.82 +                                      u.firmware_info.u.disk_mbr_signature)
    2.83 +                   ? -EFAULT : 0);
    2.84 +            break;
    2.85 +        }
    2.86 +        default:
    2.87 +            ret = -EINVAL;
    2.88 +            break;
    2.89 +        }
    2.90 +        break;
    2.91 +
    2.92      default:
    2.93          ret = -ENOSYS;
    2.94          break;
     3.1 --- a/xen/arch/x86/setup.c	Wed Jun 20 17:07:15 2007 +0100
     3.2 +++ b/xen/arch/x86/setup.c	Wed Jun 20 18:43:04 2007 +0100
     3.3 @@ -505,7 +505,7 @@ void __init __start_xen(unsigned long mb
     3.4  
     3.5      printk("Disc information:\n");
     3.6      printk(" Found %d MBR signatures\n",
     3.7 -           bootsym(boot_edd_signature_nr));
     3.8 +           bootsym(boot_mbr_signature_nr));
     3.9      printk(" Found %d EDD information structures\n",
    3.10             bootsym(boot_edd_info_nr));
    3.11  
     4.1 --- a/xen/include/asm-x86/edd.h	Wed Jun 20 17:07:15 2007 +0100
     4.2 +++ b/xen/include/asm-x86/edd.h	Wed Jun 20 18:43:04 2007 +0100
     4.3 @@ -32,12 +32,22 @@ struct edd_info {
     4.4      u16 legacy_max_cylinder;     /* %cl[7:6]:%ch: maximum cylinder number */
     4.5      u8 legacy_max_head;          /* %dh: maximum head number */
     4.6      u8 legacy_sectors_per_track; /* %cl[5:0]: maximum sector number */
     4.7 -    /* Int13, Fn41: Get Device Parameters */
     4.8 -    u8 edd_device_params[74];    /* as filled into %ds:%si */
     4.9 +    /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
    4.10 +    struct {
    4.11 +        u16 length;
    4.12 +        u8 data[72];
    4.13 +    } edd_device_params;
    4.14  } __attribute__ ((packed));
    4.15  
    4.16 -extern u32 boot_edd_signature[];
    4.17 -extern u8 boot_edd_signature_nr;
    4.18 +struct mbr_signature {
    4.19 +    u8 device;
    4.20 +    u8 pad[3];
    4.21 +    u32 signature;
    4.22 +} __attribute__ ((packed));
    4.23 +
    4.24 +/* These all reside in the boot trampoline. Access via bootsym(). */
    4.25 +extern struct mbr_signature boot_mbr_signature[];
    4.26 +extern u8 boot_mbr_signature_nr;
    4.27  extern struct edd_info boot_edd_info[];
    4.28  extern u8 boot_edd_info_nr;
    4.29  
     5.1 --- a/xen/include/public/platform.h	Wed Jun 20 17:07:15 2007 +0100
     5.2 +++ b/xen/include/public/platform.h	Wed Jun 20 18:43:04 2007 +0100
     5.3 @@ -114,6 +114,37 @@ struct xenpf_platform_quirk {
     5.4  typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
     5.5  DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
     5.6  
     5.7 +#define XENPF_firmware_info       50
     5.8 +#define XEN_FW_DISK_INFO          1
     5.9 +#define XEN_FW_DISK_MBR_SIGNATURE 2
    5.10 +struct xenpf_firmware_info {
    5.11 +    /* IN variables. */
    5.12 +    uint32_t type;
    5.13 +    uint32_t index;
    5.14 +    /* OUT variables. */
    5.15 +    union {
    5.16 +        struct {
    5.17 +            /* Int13, Fn48: Check Extensions Present. */
    5.18 +            uint8_t device;                   /* %dl: bios device number */
    5.19 +            uint8_t version;                  /* %ah: major version      */
    5.20 +            uint16_t interface_support;       /* %cx: support bitmap     */
    5.21 +            /* Int13, Fn08: Legacy Get Device Parameters. */
    5.22 +            uint16_t legacy_max_cylinder;     /* %cl[7:6]:%ch: max cyl # */
    5.23 +            uint8_t legacy_max_head;          /* %dh: max head #         */
    5.24 +            uint8_t legacy_sectors_per_track; /* %cl[5:0]: max sector #  */
    5.25 +            /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
    5.26 +            /* NB. First uint16_t of buffer must be set to buffer size.      */
    5.27 +            XEN_GUEST_HANDLE(void) edd_params;
    5.28 +        } disk_info; /* XEN_FW_DISK_INFO */
    5.29 +        struct {
    5.30 +            uint8_t device;                   /* bios device number  */
    5.31 +            uint32_t mbr_signature;           /* offset 0x1b8 in mbr */
    5.32 +        } disk_mbr_signature; /* XEN_FW_DISK_MBR_SIGNATURE */
    5.33 +    } u;
    5.34 +};
    5.35 +typedef struct xenpf_firmware_info xenpf_firmware_info_t;
    5.36 +DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
    5.37 +
    5.38  struct xen_platform_op {
    5.39      uint32_t cmd;
    5.40      uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
    5.41 @@ -124,6 +155,7 @@ struct xen_platform_op {
    5.42          struct xenpf_read_memtype      read_memtype;
    5.43          struct xenpf_microcode_update  microcode;
    5.44          struct xenpf_platform_quirk    platform_quirk;
    5.45 +        struct xenpf_firmware_info     firmware_info;
    5.46          uint8_t                        pad[128];
    5.47      } u;
    5.48  };