# 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
|