mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
EFI: move x86 specific disk probing code
Move x86 specific disk (EDD) probing to arch specific file. This code is x86 only and relates to legacy BIOS handling of disk drives. Signed-off-by: Roy Franz <roy.franz@linaro.org> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
fbc3d9a220
commit
b4bfea5532
2 files changed
+153
-143
No files matched your search
@@ -302,3 +302,155 @@ static void __init efi_arch_handle_cmdline(CHAR16 *image_name,
|
||||
mbi.boot_loader_name = (long)"EFI";
|
||||
mbi.mods_addr = (long)mb_modules;
|
||||
}
|
||||
|
||||
static void __init efi_arch_edd(void)
|
||||
{
|
||||
static EFI_GUID __initdata bio_guid = BLOCK_IO_PROTOCOL;
|
||||
static EFI_GUID __initdata devp_guid = DEVICE_PATH_PROTOCOL;
|
||||
EFI_HANDLE *handles = NULL;
|
||||
unsigned int i;
|
||||
UINTN size;
|
||||
EFI_STATUS status;
|
||||
|
||||
/* 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 *)¶ms->key; p < ¶ms->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;
|
||||
}
|
||||
+1
-143
@@ -660,8 +660,6 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
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;
|
||||
static EFI_GUID __initdata shim_lock_guid = SHIM_LOCK_PROTOCOL_GUID;
|
||||
EFI_LOADED_IMAGE *loaded_image;
|
||||
EFI_STATUS status;
|
||||
@@ -948,147 +946,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 *)¶ms->key; p < ¶ms->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;
|
||||
efi_arch_edd();
|
||||
|
||||
/* XXX Collect EDID info. */
|
||||
|
||||
|
||||