552 lines
20 KiB
Diff
552 lines
20 KiB
Diff
Index: 2007-05-14/xen/arch/x86/Makefile
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/Makefile 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/Makefile 2007-07-02 11:55:01.000000000 +0200
|
|
@@ -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-05-14/xen/arch/x86/boot/edd.S
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-05-14/xen/arch/x86/boot/edd.S 2007-07-02 12:05:50.000000000 +0200
|
|
@@ -0,0 +1,217 @@
|
|
+/*
|
|
+ * BIOS Enhanced Disk Drive support
|
|
+ * Copyright (C) 2002, 2003, 2004 Dell, Inc.
|
|
+ * by Matt Domsch <Matt_Domsch@dell.com> October 2002
|
|
+ * conformant to T13 Committee www.t13.org
|
|
+ * projects 1572D, 1484D, 1386D, 1226DT
|
|
+ * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
|
|
+ * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
|
|
+ * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
|
|
+ * March 2004
|
|
+ * Command line option parsing, Matt Domsch, November 2004
|
|
+ * Xen adoption by Jan Beulich <jbeulich@novell.com>, February 2007
|
|
+ */
|
|
+
|
|
+#include <asm/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-05-14/xen/arch/x86/boot/realmode.S
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/boot/realmode.S 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/boot/realmode.S 2007-07-02 11:55:01.000000000 +0200
|
|
@@ -120,3 +120,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-05-14/xen/arch/x86/boot/x86_32.S
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/boot/x86_32.S 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/boot/x86_32.S 2007-07-02 11:55:01.000000000 +0200
|
|
@@ -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-05-14/xen/arch/x86/boot/x86_64.S
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/boot/x86_64.S 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/boot/x86_64.S 2007-07-02 11:55:01.000000000 +0200
|
|
@@ -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-05-14/xen/arch/x86/platform_hypercall.c
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/arch/x86/platform_hypercall.c 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/arch/x86/platform_hypercall.c 2007-07-02 11:55:16.000000000 +0200
|
|
@@ -20,14 +20,21 @@
|
|
#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);
|
|
+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,66 @@ 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 >= edd.edd_info_nr )
|
|
+ break;
|
|
+
|
|
+ info = edd.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;
|
|
+
|
|
+ /* 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:
|
|
+ ret = -ESRCH;
|
|
+ if ( op->u.firmware_info.index >= edd.mbr_signature_nr )
|
|
+ break;
|
|
+
|
|
+ op->u.firmware_info.u.disk_mbr_signature.device =
|
|
+ 0x80 + op->u.firmware_info.index;
|
|
+ op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
|
|
+ edd.mbr_signature[op->u.firmware_info.index];
|
|
+
|
|
+ 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;
|
|
break;
|
|
@@ -161,6 +228,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-05-14/xen/include/public/platform.h
|
|
===================================================================
|
|
--- 2007-05-14.orig/xen/include/public/platform.h 2007-07-02 12:05:34.000000000 +0200
|
|
+++ 2007-05-14/xen/include/public/platform.h 2007-07-02 11:55:01.000000000 +0200
|
|
@@ -114,6 +114,37 @@ 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/41/48 */
|
|
+#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
|
|
+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;
|
|
};
|
|
Index: 2007-05-14/xen/include/asm-x86/edd.h
|
|
===================================================================
|
|
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
|
+++ 2007-05-14/xen/include/asm-x86/edd.h 2007-07-02 11:27:08.000000000 +0200
|
|
@@ -0,0 +1,90 @@
|
|
+/*
|
|
+ * xen/include/linux/edd.h
|
|
+ * Copyright (C) 2002, 2003, 2004 Dell Inc.
|
|
+ * by Matt Domsch <Matt_Domsch@dell.com>
|
|
+ * Adopted for Xen (C) 2007 Novell, Inc.
|
|
+ * by Jan Beulich <jbeulich@novell.com>
|
|
+ *
|
|
+ * 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
|
|
+ *
|
|
+ * 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_info {
|
|
+ /* Int13, Fn48: Check Extensions Present. */
|
|
+ u8 device; /* %dl: device */
|
|
+ u8 version; /* %ah: major version */
|
|
+ u16 interface_support; /* %cx: interface support bitmap */
|
|
+ /* Int13, Fn08: Legacy Get Device Parameters. */
|
|
+ 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 (as filled into %ds:%esi). */
|
|
+ struct {
|
|
+ u16 length;
|
|
+ u8 data[72];
|
|
+ } edd_device_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 */
|