WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] x86-64/EFI: construct EDD data from devic

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86-64/EFI: construct EDD data from device path protocol information
From: Xen patchbot-unstable <patchbot@xxxxxxx>
Date: Sat, 20 Aug 2011 07:11:08 +0100
Delivery-date: Fri, 19 Aug 2011 23:11:25 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxxxx>
# Date 1313744120 -3600
# Node ID e35c5202625ef5534561f84352833ad9467d986c
# Parent  dd90b59cb11c60c48e174c899190e2967341fe32
x86-64/EFI: construct EDD data from device path protocol information

In the absence of a BIOS to handle INT13 requests, this information
must be constructed artificially instead when booted from EFI.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---


diff -r dd90b59cb11c -r e35c5202625e xen/arch/x86/boot/edd.S
--- a/xen/arch/x86/boot/edd.S   Fri Aug 19 09:54:53 2011 +0100
+++ b/xen/arch/x86/boot/edd.S   Fri Aug 19 09:55:20 2011 +0100
@@ -16,21 +16,13 @@
  * Updated and ported for Xen by Keir Fraser <keir@xxxxxxxxxxxxx> June 2007
  */
 
+#include <asm/edd.h>
+
         .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_mbr_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
diff -r dd90b59cb11c -r e35c5202625e xen/arch/x86/efi/boot.c
--- a/xen/arch/x86/efi/boot.c   Fri Aug 19 09:54:53 2011 +0100
+++ b/xen/arch/x86/efi/boot.c   Fri Aug 19 09:55:20 2011 +0100
@@ -16,6 +16,7 @@
 #include <xen/stringify.h>
 #include <xen/vga.h>
 #include <asm/e820.h>
+#include <asm/edd.h>
 #include <asm/mm.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
@@ -539,6 +540,18 @@
     *s = 0;
 }
 
+static void __init edd_put_string(u8 *dst, size_t n, const char *src)
+{
+    while ( n-- && *src )
+       *dst++ = *src++;
+    if ( *src )
+       PrintErrMesg(L"Internal error populating EDD info",
+                    EFI_BUFFER_TOO_SMALL);
+    while ( n-- )
+       *dst++ = ' ';
+}
+#define edd_put_string(d, s) edd_put_string(d, ARRAY_SIZE(d), s)
+
 static int __init set_color(u32 mask, int bpp, u8 *pos, u8 *sz)
 {
    if ( bpp < 0 )
@@ -607,6 +620,8 @@
 {
     static EFI_GUID __initdata loaded_image_guid = LOADED_IMAGE_PROTOCOL;
     static EFI_GUID __initdata gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+    static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
+    static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
     EFI_LOADED_IMAGE *loaded_image;
     EFI_STATUS status;
     unsigned int i, argc;
@@ -887,7 +902,148 @@
 
     place_string(&mbi.mem_upper, NULL);
 
-    /* XXX Collect EDD info. */
+    /* Collect EDD info. */
+    BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
+    BUILD_BUG_ON(sizeof(struct edd_device_params) != EDDPARMSIZE);
+    size = 0;
+    status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size, NULL);
+    if ( status == EFI_BUFFER_TOO_SMALL )
+        status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
+    if ( !EFI_ERROR(status) )
+        status = efi_bs->LocateHandle(ByProtocol, &bio_guid, NULL, &size,
+                                      handles);
+    if ( EFI_ERROR(status) )
+        size = 0;
+    for ( i = 0; i < size / sizeof(*handles); ++i )
+    {
+        EFI_BLOCK_IO *bio;
+        EFI_DEV_PATH_PTR devp;
+        struct edd_info *info = boot_edd_info + boot_edd_info_nr;
+        struct edd_device_params *params = &info->edd_device_params;
+        enum { root, acpi, pci, ctrlr } state = root;
+
+        status = efi_bs->HandleProtocol(handles[i], &bio_guid, (void **)&bio);
+        if ( EFI_ERROR(status) ||
+             bio->Media->RemovableMedia ||
+             bio->Media->LogicalPartition )
+            continue;
+        if ( boot_edd_info_nr < EDD_INFO_MAX )
+        {
+            info->device = 0x80 + boot_edd_info_nr; /* fake */
+            info->version = 0x11;
+            params->length = offsetof(struct edd_device_params, dpte_ptr);
+            params->number_of_sectors = bio->Media->LastBlock + 1;
+            params->bytes_per_sector = bio->Media->BlockSize;
+            params->dpte_ptr = ~0;
+        }
+        ++boot_edd_info_nr;
+        status = efi_bs->HandleProtocol(handles[i], &devp_guid,
+                                        (void **)&devp);
+        if ( EFI_ERROR(status) )
+            continue;
+        for ( ; !IsDevicePathEnd(devp.DevPath);
+              devp.DevPath = NextDevicePathNode(devp.DevPath) )
+        {
+            switch ( DevicePathType(devp.DevPath) )
+            {
+                const u8 *p;
+
+            case ACPI_DEVICE_PATH:
+                if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
+                    break;
+                switch ( DevicePathSubType(devp.DevPath) )
+                {
+                case ACPI_DP:
+                    if ( devp.Acpi->HID != EISA_PNP_ID(0xA03) &&
+                         devp.Acpi->HID != EISA_PNP_ID(0xA08) )
+                        break;
+                    params->interface_path.pci.bus = devp.Acpi->UID;
+                    state = acpi;
+                    break;
+                case EXPANDED_ACPI_DP:
+                    /* XXX */
+                    break;
+                }
+                break;
+            case HARDWARE_DEVICE_PATH:
+                if ( state != acpi ||
+                     DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
+                     boot_edd_info_nr > EDD_INFO_MAX )
+                    break;
+                state = pci;
+                edd_put_string(params->host_bus_type, "PCI");
+                params->interface_path.pci.slot = devp.Pci->Device;
+                params->interface_path.pci.function = devp.Pci->Function;
+                break;
+            case MESSAGING_DEVICE_PATH:
+                if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
+                    break;
+                state = ctrlr;
+                switch ( DevicePathSubType(devp.DevPath) )
+                {
+                case MSG_ATAPI_DP:
+                    edd_put_string(params->interface_type, "ATAPI");
+                    params->interface_path.pci.channel =
+                        devp.Atapi->PrimarySecondary;
+                    params->device_path.atapi.device = devp.Atapi->SlaveMaster;
+                    params->device_path.atapi.lun = devp.Atapi->Lun;
+                    break;
+                case MSG_SCSI_DP:
+                    edd_put_string(params->interface_type, "SCSI");
+                    params->device_path.scsi.id = devp.Scsi->Pun;
+                    params->device_path.scsi.lun = devp.Scsi->Lun;
+                    break;
+                case MSG_FIBRECHANNEL_DP:
+                    edd_put_string(params->interface_type, "FIBRE");
+                    params->device_path.fibre.wwid = devp.FibreChannel->WWN;
+                    params->device_path.fibre.lun = devp.FibreChannel->Lun;
+                    break;
+                case MSG_1394_DP:
+                    edd_put_string(params->interface_type, "1394");
+                    params->device_path.i1394.eui = devp.F1394->Guid;
+                    break;
+                case MSG_USB_DP:
+                case MSG_USB_CLASS_DP:
+                    edd_put_string(params->interface_type, "USB");
+                    break;
+                case MSG_I2O_DP:
+                    edd_put_string(params->interface_type, "I2O");
+                    params->device_path.i2o.identity_tag = devp.I2O->Tid;
+                    break;
+                default:
+                    continue;
+                }
+                info->version = 0x30;
+                params->length = sizeof(struct edd_device_params);
+                params->key = 0xbedd;
+                params->device_path_info_length =
+                    sizeof(struct edd_device_params) -
+                    offsetof(struct edd_device_params, key);
+                for ( p = (const u8 *)&params->key; p < &params->checksum; ++p 
)
+                    params->checksum -= *p;
+                break;
+            case MEDIA_DEVICE_PATH:
+                if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
+                     devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
+                     boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
+                {
+                    struct mbr_signature *sig = boot_mbr_signature +
+                                                boot_mbr_signature_nr;
+
+                    sig->device = 0x80 + boot_edd_info_nr; /* fake */
+                    memcpy(&sig->signature, devp.HardDrive->Signature,
+                           sizeof(sig->signature));
+                    ++boot_mbr_signature_nr;
+                }
+                break;
+            }
+        }
+    }
+    if ( handles )
+        efi_bs->FreePool(handles);
+    if ( boot_edd_info_nr > EDD_INFO_MAX )
+        boot_edd_info_nr = EDD_INFO_MAX;
+
     /* XXX Collect EDID info. */
 
     if ( cpuid_eax(0x80000000) > 0x80000000 )
diff -r dd90b59cb11c -r e35c5202625e xen/include/asm-x86/edd.h
--- a/xen/include/asm-x86/edd.h Fri Aug 19 09:54:53 2011 +0100
+++ b/xen/include/asm-x86/edd.h Fri Aug 19 09:55:20 2011 +0100
@@ -23,6 +23,8 @@
 #ifndef __XEN_EDD_H__
 #define __XEN_EDD_H__
 
+#ifndef __ASSEMBLY__
+
 struct edd_info {
     /* Int13, Fn48: Check Extensions Present. */
     u8 device;                   /* %dl: device */
@@ -33,10 +35,106 @@
     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 {
+    struct edd_device_params {
         u16 length;
-        u8 data[72];
-    } edd_device_params;
+        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;
+        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)) edd_device_params;
 } __attribute__ ((packed));
 
 struct mbr_signature {
@@ -51,4 +149,16 @@
 extern struct edd_info boot_edd_info[];
 extern u8 boot_edd_info_nr;
 
+#endif /* __ASSEMBLY__ */
+
+/* Maximum number of EDD information structures at boot_edd_info. */
+#define EDD_INFO_MAX            6
+
+/* Maximum number of MBR signatures at boot_mbr_signature. */
+#define EDD_MBR_SIG_MAX         16
+
+/* Size of components of EDD information structure. */
+#define EDDEXTSIZE              8
+#define EDDPARMSIZE             74
+
 #endif /* __XEN_EDD_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86-64/EFI: construct EDD data from device path protocol information, Xen patchbot-unstable <=