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
|