[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] x86: real mode support: get EDD info
Obtain EDD info from BIOS and pass it up to Dom0. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> Index: 2007-02-27/xen/arch/x86/Makefile =================================================================== --- 2007-02-27.orig/xen/arch/x86/Makefile 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/arch/x86/Makefile 2007-02-22 15:57:24.000000000 +0100 @@ -78,7 +78,7 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H boot/mkelf32: boot/mkelf32.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -boot/$(TARGET_SUBARCH).o: boot/realmode.S +boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S .PHONY: clean clean:: Index: 2007-02-27/xen/arch/x86/boot/edd.S =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2007-02-27/xen/arch/x86/boot/edd.S 2007-02-21 17:45:32.000000000 +0100 @@ -0,0 +1,217 @@ +/* + * BIOS Enhanced Disk Drive support + * Copyright (C) 2002, 2003, 2004 Dell, Inc. + * by Matt Domsch <Matt_Domsch@xxxxxxxx> October 2002 + * conformant to T13 Committee www.t13.org + * projects 1572D, 1484D, 1386D, 1226DT + * disk signature read by Matt Domsch <Matt_Domsch@xxxxxxxx> + * and Andrew Wilks <Andrew_Wilks@xxxxxxxx> September 2003, June 2004 + * legacy CHS retrieval by Patrick J. LoPresti <patl@xxxxxxxxxxxxxxxxxxxxx> + * March 2004 + * Command line option parsing, Matt Domsch, November 2004 + * Xen adoption by Jan Beulich <jbeulich@xxxxxxxxxx>, February 2007 + */ + +#include <xen/edd.h> + +# It is assumed that %ds == INITSEG here + + movb $0, (EDD_MBR_SIG_NR_BUF) + movb $0, (EDDNR) + +# Check the command line for options: +# edd=of disables EDD completely (edd=off) +# edd=sk skips the MBR test (edd=skipmbr) +# edd=on re-enables EDD (edd=on) + + pushl %esi + movw $SYM_REAL(edd_mbr_sig_start), %di # Default to edd=on + + movl %cs:SYM_REAL(cmd_line_ptr), %esi + andl %esi, %esi + jz done_cl + +# Convert to a real-mode pointer in fs:si + movl %esi, %eax + shrl $4, %eax + mov %ax, %fs + andw $0xf, %si + +# fs:si has the pointer to the command line now + +# Loop through kernel command line one byte at a time. Just in +# case the loader is buggy and failed to null-terminate the command line +# terminate if we get close enough to the end of the segment that we +# cannot fit "edd=XX"... +cl_atspace: + cmpw $-5, %si # Watch for segment wraparound + jae done_cl + movl %fs:(%si), %eax + andb %al, %al # End of line? + jz done_cl + cmpl $EDD_CL_EQUALS, %eax + jz found_edd_equals + cmpb $0x20, %al # <= space consider whitespace + ja cl_skipword + incw %si + jmp cl_atspace + +cl_skipword: + cmpw $-5, %si # Watch for segment wraparound + jae done_cl + movb %fs:(%si), %al # End of string? + andb %al, %al + jz done_cl + cmpb $0x20, %al + jbe cl_atspace + incw %si + jmp cl_skipword + +found_edd_equals: +# only looking at first two characters after equals +# late overrides early on the command line, so keep going after finding something + movw %fs:4(%si), %ax + cmpw $EDD_CL_OFF, %ax # edd=of + je do_edd_off + cmpw $EDD_CL_SKIP, %ax # edd=sk + je do_edd_skipmbr + cmpw $EDD_CL_ON, %ax # edd=on + je do_edd_on + jmp cl_skipword +do_edd_skipmbr: + movw $SYM_REAL(edd_start), %di + jmp cl_skipword +do_edd_off: + movw $SYM_REAL(edd_done), %di + jmp cl_skipword +do_edd_on: + movw $SYM_REAL(edd_mbr_sig_start), %di + jmp cl_skipword + +done_cl: + popl %esi + jmpw *%di + +# 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 $EDD_MBR_SIG_BUF, %bx # store buffer ptr in bx +edd_mbr_sig_read: + movl $0xFFFFFFFF, %eax + movl %eax, (%bx) # assume failure + pushw %bx + movb $READ_SECTORS, %ah + movb $1, %al # read 1 sector + movb $0, %dh # at head 0 + movw $1, %cx # cylinder 0, sector 0 + pushw %es + pushw %ds + popw %es + movw $EDDBUF, %bx # disk's data goes into EDDBUF + pushw %dx # work around buggy BIOSes + stc # work around buggy BIOSes + int $0x13 + sti # work around buggy BIOSes + popw %dx + popw %es + popw %bx + jc edd_mbr_sig_done # on failure, we're done. + cmpb $0, %ah # some BIOSes do not set CF + jne edd_mbr_sig_done # on failure, we're done. + movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR + movl %eax, (%bx) # store success + incb (EDD_MBR_SIG_NR_BUF) # note that we stored something + incb %dl # increment to next device + addw $4, %bx # increment sig buffer ptr + cmpb $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF) # Out of space? + jb edd_mbr_sig_read # keep looping +edd_mbr_sig_done: + +# Do the BIOS Enhanced Disk Drive calls +# This consists of two calls: +# int 13h ah=41h "Check Extensions Present" +# int 13h ah=48h "Get Device Parameters" +# int 13h ah=08h "Legacy Get Device Parameters" +# +# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use +# in the boot_params at EDDBUF. The first four bytes of which are +# used to store the device number, interface support map and version +# results from fn41. The next four bytes are used to store the legacy +# cylinders, heads, and sectors from fn08. The following 74 bytes are used to +# store the results from fn48. Starting from device 80h, fn41, then fn48 +# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE). +# Then the pointer is incremented to store the data for the next call. +# This repeats until either a device doesn't exist, or until EDDMAXNR +# devices have been stored. +# The one tricky part is that ds:si always points EDDEXTSIZE bytes into +# the structure, and the fn41 and fn08 results are stored at offsets +# from there. This removes the need to increment the pointer for +# every store, and leaves it ready for the fn48 call. +# A second one-byte buffer, EDDNR, in the boot_params stores +# the number of BIOS devices which exist, up to EDDMAXNR. +# In setup.c, copy_edd() stores both boot_params buffers away +# for later use, as they would get overwritten otherwise. +# This code is sensitive to the size of the structs in edd.h +edd_start: + # %ds points to the bootsector + # result buffer for fn48 + movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results + # kept just before that + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $CHECKEXTENSIONSPRESENT, %ah # Function 41 + movw $EDDMAGIC1, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $EDDMAGIC2, %bx # is magic right? + jne edd_next # nope, next... + + movb %dl, %ds:-8(%si) # store device number + movb %ah, %ds:-7(%si) # store version + movw %cx, %ds:-6(%si) # store extensions + incb (EDDNR) # note that we stored something + +edd_get_device_params: + movw $EDDPARMSIZE, %ds:(%si) # put size + movw $0x0, %ds:2(%si) # work around buggy BIOSes + movb $GETDEVICEPARAMETERS, %ah # Function 48 + int $0x13 # make the call + # Don't check for fail return + # it doesn't matter. +edd_get_legacy_chs: + xorw %ax, %ax + movw %ax, %ds:-4(%si) + movw %ax, %ds:-2(%si) + # Ralf Brown's Interrupt List says to set ES:DI to + # 0000h:0000h "to guard against BIOS bugs" + pushw %es + movw %ax, %es + movw %ax, %di + pushw %dx # legacy call clobbers %dl + movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08 + int $0x13 # make the call + jc edd_legacy_done # failed + movb %cl, %al # Low 6 bits are max + andb $0x3F, %al # sector number + movb %al, %ds:-1(%si) # Record max sect + movb %dh, %ds:-2(%si) # Record max head number + movb %ch, %al # Low 8 bits of max cyl + shr $6, %cl + movb %cl, %ah # High 2 bits of max cyl + movw %ax, %ds:-4(%si) + +edd_legacy_done: + popw %dx + popw %es + movw %si, %ax # increment si + addw $EDDPARMSIZE+EDDEXTSIZE, %ax + movw %ax, %si + +edd_next: + incb %dl # increment to next device + cmpb $EDDMAXNR, (EDDNR) # Out of space? + jb edd_check_ext # keep looping + +edd_done: Index: 2007-02-27/xen/arch/x86/boot/realmode.S =================================================================== --- 2007-02-27.orig/xen/arch/x86/boot/realmode.S 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/arch/x86/boot/realmode.S 2007-02-22 15:58:16.000000000 +0100 @@ -118,3 +118,26 @@ cmd_line_ptr: .long 0 .Lgdt: .skip 2+4 .Lidt: .skip 2+4 .previous + +#define EDDNR SYM_REAL(eddnr) +#define EDDBUF SYM_REAL(eddbuf) +#define EDD_MBR_SIG_NR_BUF SYM_REAL(edd_mbr_sig_nr_buf) +#define EDD_MBR_SIG_BUF SYM_REAL(edd_mbr_sig_buf) + +edd: +#include "edd.S" + ret + + .section .real.data + .globl eddnr, eddbuf, edd_mbr_sig_nr_buf, edd_mbr_sig_buf + .align 4 +eddbuf: .skip EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE) +#if EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE) < 512 +/* Must have space for a full 512-byte sector */ + .skip 512 - EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE) +#endif + .align 4 +edd_mbr_sig_buf: .skip EDD_MBR_SIG_MAX * 4 +eddnr: .skip 1 +edd_mbr_sig_nr_buf: .skip 1 + .previous Index: 2007-02-27/xen/arch/x86/boot/x86_32.S =================================================================== --- 2007-02-27.orig/xen/arch/x86/boot/x86_32.S 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/arch/x86/boot/x86_32.S 2007-02-21 18:08:44.000000000 +0100 @@ -90,6 +90,9 @@ __start: lea __PAGE_OFFSET(%ebx),%eax push %eax + pushl $SYM_PHYS(edd) + call realmode + #ifdef CONFIG_X86_PAE /* Initialize low and high mappings of all memory with 2MB pages */ mov $SYM_PHYS(idle_pg_table_l2),%edi Index: 2007-02-27/xen/arch/x86/boot/x86_64.S =================================================================== --- 2007-02-27.orig/xen/arch/x86/boot/x86_64.S 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/arch/x86/boot/x86_64.S 2007-02-21 17:55:02.000000000 +0100 @@ -73,6 +73,8 @@ __start: mov %ebx,SYM_PHYS(multiboot_ptr) lss SYM_PHYS(.Lstack_start),%esp + pushl $SYM_PHYS(edd) + call realmode /* We begin by interrogating the CPU for the presence of long mode. */ mov $0x80000000,%eax Index: 2007-02-27/xen/arch/x86/platform_hypercall.c =================================================================== --- 2007-02-27.orig/xen/arch/x86/platform_hypercall.c 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/arch/x86/platform_hypercall.c 2007-02-22 16:14:39.000000000 +0100 @@ -17,6 +17,7 @@ #include <xen/trace.h> #include <xen/console.h> #include <xen/iocap.h> +#include <xen/edd.h> #include <xen/guest_access.h> #include <asm/current.h> #include <public/platform.h> @@ -26,8 +27,14 @@ #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 +158,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 +235,19 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe return ret; } +#ifndef COMPAT +static int __init firmware_init(void) +{ + memcpy(edd.mbr_signature, edd_mbr_sig_buf, sizeof(edd.mbr_signature)); + memcpy(edd.edd_info, eddbuf, sizeof(edd.edd_info)); + edd.mbr_signature_nr = edd_mbr_sig_nr_buf; + edd.edd_info_nr = eddnr; + + return 0; +} +__initcall(firmware_init); +#endif + /* * Local variables: * mode: C Index: 2007-02-27/xen/include/public/platform.h =================================================================== --- 2007-02-27.orig/xen/include/public/platform.h 2007-02-22 16:14:25.000000000 +0100 +++ 2007-02-27/xen/include/public/platform.h 2007-02-21 14:51:00.000000000 +0100 @@ -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; }; Index: 2007-02-27/xen/include/xen/edd.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2007-02-27/xen/include/xen/edd.h 2007-02-21 12:19:19.000000000 +0100 @@ -0,0 +1,193 @@ +/* + * xen/include/linux/edd.h + * Copyright (C) 2002, 2003, 2004 Dell Inc. + * by Matt Domsch <Matt_Domsch@xxxxxxxx> + * Adopted for Xen (C) 2007 Novell, Inc. + * by Jan Beulich <jbeulich@xxxxxxxxxx> + * + * structures and definitions for the int 13h, ax={41,48}h + * BIOS Enhanced Disk Drive Services + * This is based on the T13 group document D1572 Revision 0 (August 14 2002) + * available at http://www.t13.org/docs2002/d1572r0.pdf. It is + * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf + * + * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch + * table in the boot_params that contains a list of BIOS-enumerated + * boot devices. + * In arch/{i386,x86_64}/kernel/setup.c, this information is + * transferred into the edd structure, and in drivers/firmware/edd.c, that + * information is used to identify BIOS boot disk. The code in setup.S + * is very sensitive to the size of these structures. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License v2.0 as published by + * the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef _XEN_EDD_H +#define _XEN_EDD_H + +#define EDDMAXNR 6 /* number of edd_info structs starting at eddbuf */ +#define EDDEXTSIZE 8 /* change these if you muck with the structures */ +#define EDDPARMSIZE 74 +#define CHECKEXTENSIONSPRESENT 0x41 +#define GETDEVICEPARAMETERS 0x48 +#define LEGACYGETDEVICEPARAMETERS 0x08 +#define EDDMAGIC1 0x55AA +#define EDDMAGIC2 0xAA55 + + +#define READ_SECTORS 0x02 /* int13 AH=0x02 is READ_SECTORS command */ +#define EDD_MBR_SIG_OFFSET 0x1B8 /* offset of signature in the MBR */ +#define EDD_MBR_SIG_MAX 16 /* max number of signatures to store */ +#define EDD_CL_EQUALS 0x3d646465 /* "edd=" */ +#define EDD_CL_OFF 0x666f /* "of" for off */ +#define EDD_CL_SKIP 0x6b73 /* "sk" for skipmbr */ +#define EDD_CL_ON 0x6e6f /* "on" for on */ + +#ifndef __ASSEMBLY__ + +#define EDD_EXT_FIXED_DISK_ACCESS (1 << 0) +#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1) +#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2) +#define EDD_EXT_64BIT_EXTENSIONS (1 << 3) + +#define EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT (1 << 0) +#define EDD_INFO_GEOMETRY_VALID (1 << 1) +#define EDD_INFO_REMOVABLE (1 << 2) +#define EDD_INFO_WRITE_VERIFY (1 << 3) +#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION (1 << 4) +#define EDD_INFO_LOCKABLE (1 << 5) +#define EDD_INFO_NO_MEDIA_PRESENT (1 << 6) +#define EDD_INFO_USE_INT13_FN50 (1 << 7) + +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 { + u8 device; + u8 version; + u16 interface_support; + u16 legacy_max_cylinder; + u8 legacy_max_head; + u8 legacy_sectors_per_track; + struct edd_device_params params; +} __attribute__ ((packed)); + +struct edd { + unsigned int mbr_signature[EDD_MBR_SIG_MAX]; + struct edd_info edd_info[EDDMAXNR]; + unsigned char mbr_signature_nr; + unsigned char edd_info_nr; +}; + +extern unsigned char eddnr, edd_mbr_sig_nr_buf; +extern struct edd_info eddbuf[]; +extern unsigned int edd_mbr_sig_buf[]; + +#endif /*!__ASSEMBLY__ */ + +#endif /* _XEN_EDD_H */ Index: 2007-02-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c 2007-02-21 16:57:23.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c 2007-02-21 14:24:52.000000000 +0100 @@ -66,6 +66,7 @@ #include <xen/interface/physdev.h> #include <xen/interface/memory.h> #include <xen/features.h> +#include <xen/firmware.h> #include <xen/xencons.h> #include <setup_arch.h> #include <bios_ebda.h> @@ -740,6 +741,7 @@ struct edd edd; #ifdef CONFIG_EDD_MODULE EXPORT_SYMBOL(edd); #endif +#ifndef CONFIG_XEN /** * copy_edd() - Copy the BIOS EDD information * from boot_params into a safe place. @@ -752,6 +754,7 @@ static inline void copy_edd(void) edd.mbr_signature_nr = EDD_MBR_SIG_NR; edd.edd_info_nr = EDD_NR; } +#endif #else static inline void copy_edd(void) { Index: 2007-02-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c 2007-02-21 16:57:23.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c 2007-02-21 14:25:07.000000000 +0100 @@ -71,6 +71,7 @@ #include <asm/hypervisor.h> #include <xen/interface/nmi.h> #include <xen/features.h> +#include <xen/firmware.h> #include <xen/xencons.h> #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_PHYS(x) ((x) << PAGE_SHIFT) @@ -534,6 +535,7 @@ struct edd edd; #ifdef CONFIG_EDD_MODULE EXPORT_SYMBOL(edd); #endif +#ifndef CONFIG_XEN /** * copy_edd() - Copy the BIOS EDD information * from boot_params into a safe place. @@ -546,6 +548,7 @@ static inline void copy_edd(void) edd.mbr_signature_nr = EDD_MBR_SIG_NR; edd.edd_info_nr = EDD_NR; } +#endif #else static inline void copy_edd(void) { Index: 2007-02-27/linux-2.6-xen-sparse/drivers/firmware/Kconfig =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/drivers/firmware/Kconfig 2007-02-21 16:57:23.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/drivers/firmware/Kconfig 2007-02-21 14:19:11.000000000 +0100 @@ -8,7 +8,6 @@ menu "Firmware Drivers" config EDD tristate "BIOS Enhanced Disk Drive calls determine boot disk" depends on !IA64 - depends on !XEN help Say Y or M here if you want to enable BIOS Enhanced Disk Drive Services real mode BIOS calls to determine which disk Index: 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/Makefile =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/drivers/xen/core/Makefile 2007-02-21 16:57:42.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/Makefile 2007-02-21 17:02:28.000000000 +0100 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := evtchn.o gnttab.o features.o +obj-y := evtchn.o gnttab.o features.o firmware.o obj-$(CONFIG_PROC_FS) += xen_proc.o obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o Index: 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/firmware.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2007-02-27/linux-2.6-xen-sparse/drivers/xen/core/firmware.c 2007-02-21 17:09:28.000000000 +0100 @@ -0,0 +1,61 @@ +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/edd.h> +#include <xen/interface/platform.h> +#include <asm/hypervisor.h> + +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +void __init copy_edd(void) +{ + int ret; + xen_platform_op_t op; + + if (!is_initial_xendomain()) + return; + + op.cmd = XENPF_firmware_info; + + for (op.u.firmware_info.index = 0, ret = 0; + ret != -ESRCH && ret != -ENOSYS && edd.edd_info_nr < EDDMAXNR; + ++op.u.firmware_info.index) { + struct edd_info *info = edd.edd_info + edd.edd_info_nr; + + op.u.firmware_info.type = XEN_FW_EDD_INFO; + ret = HYPERVISOR_platform_op(&op); + if (ret) + continue; + info->device = op.u.firmware_info.u.edd_info.device; + info->version = op.u.firmware_info.u.edd_info.version; + info->interface_support = op.u.firmware_info.u.edd_info.interface; + + op.u.firmware_info.type = XEN_FW_DISK_INFO; + ret = HYPERVISOR_platform_op(&op); + if (ret) + continue; + info->legacy_max_cylinder = op.u.firmware_info.u.disk_info.max_cylinder; + info->legacy_max_head = op.u.firmware_info.u.disk_info.max_head; + info->legacy_sectors_per_track = op.u.firmware_info.u.disk_info.sectors_per_track; + + op.u.firmware_info.type = XEN_FW_EDD_PARAMS; + info->params.length = sizeof(info->params); + set_xen_guest_handle(op.u.firmware_info.u.edd_params, &info->params); + ret = HYPERVISOR_platform_op(&op); + if (ret) + continue; + + ++edd.edd_info_nr; + } + + op.u.firmware_info.type = XEN_FW_MBR_SIGNATURE; + for (op.u.firmware_info.index = 0, ret = 0; + ret != -ESRCH && ret != -ENOSYS && edd.mbr_signature_nr < EDD_MBR_SIG_MAX; + ++op.u.firmware_info.index) { + + ret = HYPERVISOR_platform_op(&op); + if (ret) + continue; + edd.mbr_signature[edd.mbr_signature_nr++] = op.u.firmware_info.u.mbr_signature; + } +} +#endif Index: 2007-02-27/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h 2007-02-21 16:57:23.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h 2007-02-21 14:59:20.000000000 +0100 @@ -209,6 +209,14 @@ HYPERVISOR_dom0_op( } static inline int +HYPERVISOR_platform_op( + xen_platform_op_t *platform_op) +{ + platform_op->interface_version = XENPF_INTERFACE_VERSION; + return _hypercall1(int, platform_op, platform_op); +} + +static inline int HYPERVISOR_set_debugreg( int reg, unsigned long value) { Index: 2007-02-27/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h =================================================================== --- 2007-02-27.orig/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h 2007-02-21 16:57:23.000000000 +0100 +++ 2007-02-27/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h 2007-02-21 15:01:06.000000000 +0100 @@ -212,6 +212,14 @@ HYPERVISOR_dom0_op( } static inline int +HYPERVISOR_platform_op( + xen_platform_op_t *platform_op) +{ + platform_op->interface_version = XENPF_INTERFACE_VERSION; + return _hypercall1(int, platform_op, platform_op); +} + +static inline int HYPERVISOR_set_debugreg( int reg, unsigned long value) { Index: 2007-02-27/linux-2.6-xen-sparse/include/xen/firmware.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ 2007-02-27/linux-2.6-xen-sparse/include/xen/firmware.h 2007-02-21 14:26:55.000000000 +0100 @@ -0,0 +1,6 @@ +#ifndef __XEN_FIRMWARE_H__ +#define __XEN_FIRMWARE_H__ + +void copy_edd(void); + +#endif /* __XEN_FIRMWARE_H__ */ _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |