[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Gather BIOS EDD info during boot.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1181653389 -3600 # Node ID 699f0c4296204557dee30c399ed304e677b8f6f4 # Parent be33028fcda596d6ebdca89bbb0331a1e3b417ae x86: Gather BIOS EDD info during boot. Still needs plumbing to dom0. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/boot/Makefile | 2 xen/arch/x86/boot/cmdline.S | 20 +++++ xen/arch/x86/boot/edd.S | 161 +++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/boot/trampoline.S | 9 +- xen/arch/x86/boot/video.S | 2 xen/arch/x86/setup.c | 7 + xen/include/asm-x86/edd.h | 44 +++++++++++ 7 files changed, 240 insertions(+), 5 deletions(-) diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/boot/Makefile --- a/xen/arch/x86/boot/Makefile Tue Jun 12 11:39:51 2007 +0100 +++ b/xen/arch/x86/boot/Makefile Tue Jun 12 14:03:09 2007 +0100 @@ -1,3 +1,3 @@ obj-y += head.o obj-y += head.o -head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S +head.o: head.S $(TARGET_SUBARCH).S trampoline.S mem.S video.S cmdline.S edd.S diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/boot/cmdline.S --- a/xen/arch/x86/boot/cmdline.S Tue Jun 12 11:39:51 2007 +0100 +++ b/xen/arch/x86/boot/cmdline.S Tue Jun 12 14:03:09 2007 +0100 @@ -169,6 +169,24 @@ cmdline_parse_early: test %eax,%eax setnz bootsym_phys(skip_realmode) +.Lparse_edd: + /* Check for 'edd=' command-line option. */ + movl $sym_phys(.Ledd_opt),4(%esp) + call .Lfind_option + test %eax,%eax + jz .Lparse_edid + cmpb $'=',3(%eax) + jne .Lparse_edid + add $4,%eax + movb $2,bootsym_phys(opt_edd) /* opt_edd=2: edd=off */ + cmpw $0x666f,(%eax) /* 0x666f == "of" */ + je .Lparse_edid + decb bootsym_phys(opt_edd) /* opt_edd=1: edd=skipmbr */ + cmpw $0x6b73,(%eax) /* 0x6b73 == "sk" */ + je .Lparse_edid + decb bootsym_phys(opt_edid) /* opt_edd=0: edd=on (default) */ + +.Lparse_edid: /* Check for 'edid=' command-line option. */ movl $sym_phys(.Ledid_opt),4(%esp) call .Lfind_option @@ -318,3 +336,5 @@ 1: lodsw .asciz "force" .Ledid_no: .asciz "no" +.Ledd_opt: + .asciz "edd" diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/boot/edd.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/boot/edd.S Tue Jun 12 14:03:09 2007 +0100 @@ -0,0 +1,161 @@ +/****************************************************************************** + * edd.S + * + * 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 + * + * Updated and ported for Xen by Keir Fraser <keir@xxxxxxxxxxxxx> June 2007 + */ + + .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 + +get_edd: + cmpb $2, bootsym(opt_edd) # edd=off ? + je edd_done + cmpb $1, bootsym(opt_edd) # edd=skipmbr ? + je edd_start + +# 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 +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 + movb $0, %dh # at head 0 + movw $1, %cx # cylinder 0, sector 0 + pushw %es + pushw %ds + popw %es + movw $bootsym(boot_edd_info), %bx # disk's data goes into info + 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 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 + incb %dl # increment to next device + addw $4, %bx # increment sig buffer ptr + cmpb $EDD_MBR_SIG_MAX,bootsym(boot_edd_signature_nr) + jb edd_mbr_sig_read +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 EDD_INFO_MAX*(EDDEXTSIZE+EDDPARMSIZE) is reserved at +# boot_edd_info, 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. +# This code is sensitive to the size of the structs in edd.h +edd_start: + /* ds:si points at fn48 results. Fn41 results go immediately before. */ + movw $bootsym(boot_edd_info)+EDDEXTSIZE, %si + movb $0x80, %dl # BIOS device 0x80 + +edd_check_ext: + movb $0x41, %ah # 0x41 Check Extensions Present + movw $0x55AA, %bx # magic + int $0x13 # make the call + jc edd_done # no more BIOS devices + + cmpw $0xAA55, %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 bootsym(boot_edd_info_nr) # 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 $0x48, %ah # 0x48 Get Device Parameters + 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 $0x08, %ah # 0x08 Legacy Get Device Params + 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 $EDD_INFO_MAX,bootsym(boot_edd_info_nr) + jb edd_check_ext + +edd_done: + ret + +opt_edd: + .byte 0 # edd=on/off/skipmbr + +.globl boot_edd_info_nr, boot_edd_signature_nr +boot_edd_info_nr: + .byte 0 +boot_edd_signature_nr: + .byte 0 +boot_edd_signature: + .fill EDD_MBR_SIG_MAX*4,1,0 +boot_edd_info: + .fill 512,1,0 # big enough for a disc sector diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/boot/trampoline.S --- a/xen/arch/x86/boot/trampoline.S Tue Jun 12 11:39:51 2007 +0100 +++ b/xen/arch/x86/boot/trampoline.S Tue Jun 12 14:03:09 2007 +0100 @@ -142,17 +142,19 @@ 1: mov $(BOOT_TRAMPOLINE>>4),%a mov %ax,%es mov %ax,%ss - /* Stack grows down from 0x9200. Initialise IDT and enable irqs. */ - mov $0x2000,%sp + /* Stack grows down from 0x93000. Initialise IDT and enable irqs. */ + mov $0x3000,%sp lidt bootsym(rm_idt) sti /* * Do real-mode work: * 1. Get memory map. - * 2. Set video mode. + * 2. Get Enhanced Disk Drive (EDD) information. + * 3. Set video mode. */ call get_memory_map + call get_edd call video /* Disable irqs before returning to protected mode. */ @@ -187,4 +189,5 @@ rm_idt: .word 256*4-1, 0, 0 rm_idt: .word 256*4-1, 0, 0 #include "mem.S" +#include "edd.S" #include "video.S" diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/boot/video.S --- a/xen/arch/x86/boot/video.S Tue Jun 12 11:39:51 2007 +0100 +++ b/xen/arch/x86/boot/video.S Tue Jun 12 14:03:09 2007 +0100 @@ -15,7 +15,7 @@ #include "video.h" -#define modelist (0x2000) +#define modelist (0x3000) /* Retrieve Extended Display Identification Data. */ #define CONFIG_FIRMWARE_EDID diff -r be33028fcda5 -r 699f0c429620 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Tue Jun 12 11:39:51 2007 +0100 +++ b/xen/arch/x86/setup.c Tue Jun 12 14:03:09 2007 +0100 @@ -34,6 +34,7 @@ #include <asm/e820.h> #include <acm/acm_hooks.h> #include <xen/kexec.h> +#include <asm/edd.h> #if defined(CONFIG_X86_64) #define BOOTSTRAP_DIRECTMAP_END (1UL << 32) @@ -490,6 +491,12 @@ void __init __start_xen(multiboot_info_t } } + printk("Disc information:\n"); + printk(" Found %d MBR signatures\n", + bootsym(boot_edd_signature_nr)); + printk(" Found %d EDD information structures\n", + bootsym(boot_edd_info_nr)); + /* Check that we have at least one Multiboot module. */ if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) ) EARLY_FAIL("dom0 kernel not specified. " diff -r be33028fcda5 -r 699f0c429620 xen/include/asm-x86/edd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/include/asm-x86/edd.h Tue Jun 12 14:03:09 2007 +0100 @@ -0,0 +1,44 @@ +/****************************************************************************** + * edd.h + * + * Copyright (C) 2002, 2003, 2004 Dell Inc. + * by Matt Domsch <Matt_Domsch@xxxxxxxx> + * + * 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__ + +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 */ + u8 edd_device_params[74]; /* as filled into %ds:%si */ +} __attribute__ ((packed)); + +extern u32 boot_edd_signature[]; +extern u8 boot_edd_signature_nr; +extern struct edd_info boot_edd_info[]; +extern u8 boot_edd_info_nr; + +#endif /* __XEN_EDD_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |