ia64/xen-unstable
changeset 15430: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>
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 };