# HG changeset 67+71+76 patch # User kfraser@localhost.localdomain # Date 1182362965 -3600 # Node ID 706976fe8333a88c4d3482253927faa3b4714b15 # Parent 496e3157a35c32d7a550223914cfb92389a80874 Subject: linux/x86: Obtain EDD info from Xen Signed-off-by: Jan Beulich Signed-off-by: Keir Fraser --- arch/i386/kernel/setup-xen.c | 3 ++ arch/x86_64/kernel/setup-xen.c | 3 ++ drivers/firmware/Kconfig | 1 drivers/xen/core/Makefile | 2 - drivers/xen/core/firmware.c | 55 +++++++++++++++++++++++++++++++++++++++ include/xen/firmware.h | 8 +++++ include/xen/interface/platform.h | 32 ++++++++++++++++++++++ 7 files changed, 102 insertions(+), 2 deletions(-) --- a/arch/i386/kernel/setup-xen.c 2007-08-27 14:01:24.000000000 -0400 +++ b/arch/i386/kernel/setup-xen.c 2007-08-27 14:02:09.000000000 -0400 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -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) { --- a/arch/x86_64/kernel/setup-xen.c 2007-08-27 14:01:25.000000000 -0400 +++ b/arch/x86_64/kernel/setup-xen.c 2007-08-27 14:02:09.000000000 -0400 @@ -71,6 +71,7 @@ #include #include #include +#include #include #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) { --- a/drivers/firmware/Kconfig 2007-08-27 14:01:25.000000000 -0400 +++ b/drivers/firmware/Kconfig 2007-08-27 14:01:25.000000000 -0400 @@ -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 --- a/drivers/xen/core/Makefile 2007-08-27 14:01:25.000000000 -0400 +++ b/drivers/xen/core/Makefile 2007-08-27 14:02:04.000000000 -0400 @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o +obj-y := evtchn.o gnttab.o features.o reboot.o machine_reboot.o firmware.o obj-$(CONFIG_PROC_FS) += xen_proc.o obj-$(CONFIG_SYSFS) += hypervisor_sysfs.o --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/drivers/xen/core/firmware.c 2007-08-27 14:02:09.000000000 -0400 @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +void __init copy_edd(void) +{ + int ret; + struct xen_platform_op op; + + if (!is_initial_xendomain()) + return; + + op.cmd = XENPF_firmware_info; + + op.u.firmware_info.type = XEN_FW_DISK_INFO; + for (op.u.firmware_info.index = 0; + edd.edd_info_nr < EDDMAXNR; + op.u.firmware_info.index++) { + struct edd_info *info = edd.edd_info + edd.edd_info_nr; + + info->params.length = sizeof(info->params); + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, + &info->params); + ret = HYPERVISOR_platform_op(&op); + if (ret) + break; + +#define C(x) info->x = op.u.firmware_info.u.disk_info.x + C(device); + C(version); + C(interface_support); + C(legacy_max_cylinder); + C(legacy_max_head); + C(legacy_sectors_per_track); +#undef C + + edd.edd_info_nr++; + } + + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; + for (op.u.firmware_info.index = 0; + edd.mbr_signature_nr < EDD_MBR_SIG_MAX; + op.u.firmware_info.index++) { + ret = HYPERVISOR_platform_op(&op); + if (ret) + break; + edd.mbr_signature[edd.mbr_signature_nr++] = + op.u.firmware_info.u.disk_mbr_signature.mbr_signature; + } +} +#endif --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ b/include/xen/firmware.h 2007-08-27 14:02:09.000000000 -0400 @@ -0,0 +1,8 @@ +#ifndef __XEN_FIRMWARE_H__ +#define __XEN_FIRMWARE_H__ + +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +void copy_edd(void); +#endif + +#endif /* __XEN_FIRMWARE_H__ */ --- a/include/xen/interface/platform.h 2007-08-27 14:01:25.000000000 -0400 +++ b/include/xen/interface/platform.h 2007-08-27 14:02:09.000000000 -0400 @@ -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 +#define XEN_FW_DISK_MBR_SIGNATURE 2 +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; };