[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/4] x86-64: EFI runtime code
On 28/06/2011 08:11, "Jan Beulich" <JBeulich@xxxxxxxxxx> wrote: >>>> On 27.06.11 at 18:25, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> wrote: >> On Mon, Jun 27, 2011 at 11:43:02AM +0100, Jan Beulich wrote: >>> This allows Dom0 access to all suitable EFI runtime services. The >> >> What type of patches for the upstream 3.0 kernel are needed to take >> advantage of these new hypercalls? > > I did not put any consideration in how to integrate this with the > upstream kernel. For our kernel, I used the *-xen.? mechanism > to have a parallel source file to arch/x86/platform/efi/efi.c, and > excluded building of arch/x86/platform/efi/efi_stub_*.S and > arch/x86/platform/efi/efi_*.c. > > Patch below for reference. Since the new hypercalls are 1:1 replacements for the EFI run-time calls (I think?) we could perhaps keep most of Linux's EFI subsystem intact and spoof it with a fake operations table containing hypercall stubs. -- Keir > Jan > > --- head-2011-05-23.orig/arch/x86/Kconfig 2011-04-14 11:32:40.000000000 +0200 > +++ head-2011-05-23/arch/x86/Kconfig 2011-06-09 17:04:17.000000000 +0200 > @@ -1511,7 +1511,7 @@ config ARCH_USES_PG_UNCACHED > > config EFI > bool "EFI runtime service support" > - depends on ACPI && !XEN > + depends on ACPI && !XEN_UNPRIVILEGED_GUEST > ---help--- > This enables the kernel to use EFI runtime services that are > available (such as the EFI variable services). > --- head-2011-05-23.orig/arch/x86/include/mach-xen/asm/setup.h 2011-06-21 > 15:35:45.000000000 +0200 > +++ head-2011-05-23/arch/x86/include/mach-xen/asm/setup.h 2011-06-15 > 15:26:22.000000000 +0200 > @@ -10,6 +10,12 @@ void reserve_pgtable_low(void); > > extern unsigned long xen_initrd_start; > > +#ifdef CONFIG_EFI > +void efi_probe(void); > +#else > +#define efi_probe() ((void)0) > +#endif > + > #endif > > #include_next <asm/setup.h> > --- head-2011-05-23.orig/arch/x86/kernel/setup-xen.c 2011-06-10 > 12:12:00.000000000 +0200 > +++ head-2011-05-23/arch/x86/kernel/setup-xen.c 2011-06-10 12:42:34.000000000 > +0200 > @@ -870,6 +870,8 @@ void __init setup_arch(char **cmdline_p) > xen_start_info->console.dom0.info_size); > xen_start_info->console.domU.mfn = 0; > xen_start_info->console.domU.evtchn = 0; > + > + efi_probe(); > } else > screen_info.orig_video_isVGA = 0; > copy_edid(); > --- head-2011-05-23.orig/arch/x86/platform/efi/Makefile 2011-06-21 > 15:35:45.000000000 +0200 > +++ head-2011-05-23/arch/x86/platform/efi/Makefile 2011-06-09 > 17:06:13.000000000 +0200 > @@ -1 +1,2 @@ > obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o > +disabled-obj-$(CONFIG_XEN) := efi_%$(BITS).o > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ head-2011-05-23/arch/x86/platform/efi/efi-xen.c 2011-06-21 > 15:24:29.000000000 +0200 > @@ -0,0 +1,430 @@ > +/* > + * Common EFI (Extensible Firmware Interface) support functions > + * Based on Extensible Firmware Interface Specification version 1.0 > + * > + * Copyright (C) 1999 VA Linux Systems > + * Copyright (C) 1999 Walt Drummond <drummond@xxxxxxxxxxx> > + * Copyright (C) 1999-2002 Hewlett-Packard Co. > + * David Mosberger-Tang <davidm@xxxxxxxxxx> > + * Stephane Eranian <eranian@xxxxxxxxxx> > + * Copyright (C) 2005-2008 Intel Co. > + * Fenghua Yu <fenghua.yu@xxxxxxxxx> > + * Bibo Mao <bibo.mao@xxxxxxxxx> > + * Chandramouli Narayanan <mouli@xxxxxxxxxxxxxxx> > + * Huang Ying <ying.huang@xxxxxxxxx> > + * > + * Copied from efi_32.c to eliminate the duplicated code between EFI > + * 32/64 support code. --ying 2007-10-26 > + * > + * All EFI Runtime Services are not implemented yet as EFI only > + * supports physical mode addressing on SoftSDV. This is to be fixed > + * in a future version. --drummond 1999-07-20 > + * > + * Implemented EFI runtime services and virtual mode calls. --davidm > + * > + * Goutham Rao: <goutham.rao@xxxxxxxxx> > + * Skip non-WB memory and ignore empty memory ranges. > + */ > + > +#include <linux/kernel.h> > +#include <linux/init.h> > +#include <linux/efi.h> > +#include <linux/platform_device.h> > +#include <linux/spinlock.h> > +#include <linux/time.h> > + > +#include <asm/setup.h> > +#include <asm/efi.h> > +#include <asm/time.h> > +#include <asm/cacheflush.h> > +#include <asm/tlbflush.h> > +#include <asm/x86_init.h> > + > +#include <xen/interface/platform.h> > + > +#define EFI_DEBUG 1 > +#define PFX "EFI: " > + > +int __read_mostly efi_enabled; > +EXPORT_SYMBOL(efi_enabled); > + > +#define call op.u.efi_runtime_call > +#define DECLARE_CALL(what) \ > + struct xen_platform_op op; \ > + op.cmd = XENPF_efi_runtime_call; \ > + call.function = XEN_EFI_##what; \ > + call.misc = 0 > + > +static efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) > +{ > + int err; > + DECLARE_CALL(get_time); > + > + err = HYPERVISOR_platform_op(&op); > + if (err) > + return EFI_UNSUPPORTED; > + > + if (tm) { > + BUILD_BUG_ON(sizeof(*tm) != sizeof(call.u.get_time.time)); > + memcpy(tm, &call.u.get_time.time, sizeof(*tm)); > + } > + > + if (tc) { > + tc->resolution = call.u.get_time.resolution; > + tc->accuracy = call.u.get_time.accuracy; > + tc->sets_to_zero = !!(call.misc & > + XEN_EFI_GET_TIME_SET_CLEARS_NS); > + } > + > + return call.status; > +} > + > +static efi_status_t xen_efi_set_time(efi_time_t *tm) > +{ > + DECLARE_CALL(set_time); > + > + BUILD_BUG_ON(sizeof(*tm) != sizeof(call.u.set_time)); > + memcpy(&call.u.set_time, tm, sizeof(*tm)); > + > + return HYPERVISOR_platform_op(&op) ? EFI_UNSUPPORTED : call.status; > +} > + > +static efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, > + efi_bool_t *pending, > + efi_time_t *tm) > +{ > + int err; > + DECLARE_CALL(get_wakeup_time); > + > + err = HYPERVISOR_platform_op(&op); > + if (err) > + return EFI_UNSUPPORTED; > + > + if (tm) { > + BUILD_BUG_ON(sizeof(*tm) != sizeof(call.u.get_wakeup_time)); > + memcpy(tm, &call.u.get_wakeup_time, sizeof(*tm)); > + } > + > + if (enabled) > + *enabled = !!(call.misc & XEN_EFI_GET_WAKEUP_TIME_ENABLED); > + > + if (pending) > + *pending = !!(call.misc & XEN_EFI_GET_WAKEUP_TIME_PENDING); > + > + return call.status; > +} > + > +static efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t > *tm) > +{ > + DECLARE_CALL(set_wakeup_time); > + > + BUILD_BUG_ON(sizeof(*tm) != sizeof(call.u.set_wakeup_time)); > + if (enabled) > + call.misc = XEN_EFI_SET_WAKEUP_TIME_ENABLE; > + if (tm) > + memcpy(&call.u.set_wakeup_time, tm, sizeof(*tm)); > + else > + call.misc |= XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY; > + > + return HYPERVISOR_platform_op(&op) ? EFI_UNSUPPORTED : call.status; > +} > + > +static efi_status_t xen_efi_get_variable(efi_char16_t *name, > + efi_guid_t *vendor, > + u32 *attr, > + unsigned long *data_size, > + void *data) > +{ > + int err; > + DECLARE_CALL(get_variable); > + > + set_xen_guest_handle(call.u.get_variable.name, name); > + BUILD_BUG_ON(sizeof(*vendor) != > + sizeof(call.u.get_variable.vendor_guid)); > + memcpy(&call.u.get_variable.vendor_guid, vendor, sizeof(*vendor)); > + call.u.get_variable.size = *data_size; > + set_xen_guest_handle(call.u.get_variable.data, data); > + err = HYPERVISOR_platform_op(&op); > + if (err) > + return EFI_UNSUPPORTED; > + > + *data_size = call.u.get_variable.size; > + *attr = call.misc; > + > + return call.status; > +} > + > +static efi_status_t xen_efi_get_next_variable(unsigned long *name_size, > + efi_char16_t *name, > + efi_guid_t *vendor) > +{ > + int err; > + DECLARE_CALL(get_next_variable_name); > + > + call.u.get_next_variable_name.size = *name_size; > + set_xen_guest_handle(call.u.get_next_variable_name.name, name); > + BUILD_BUG_ON(sizeof(*vendor) != > + sizeof(call.u.get_next_variable_name.vendor_guid)); > + memcpy(&call.u.get_next_variable_name.vendor_guid, vendor, > + sizeof(*vendor)); > + err = HYPERVISOR_platform_op(&op); > + if (err) > + return EFI_UNSUPPORTED; > + > + *name_size = call.u.get_next_variable_name.size; > + memcpy(vendor, &call.u.get_next_variable_name.vendor_guid, > + sizeof(*vendor)); > + > + return call.status; > +} > + > +static efi_status_t xen_efi_set_variable(efi_char16_t *name, > + efi_guid_t *vendor, > + unsigned long attr, > + unsigned long data_size, > + void *data) > +{ > + DECLARE_CALL(set_variable); > + > + set_xen_guest_handle(call.u.set_variable.name, name); > + call.misc = attr; > + BUILD_BUG_ON(sizeof(*vendor) != > + sizeof(call.u.set_variable.vendor_guid)); > + memcpy(&call.u.set_variable.vendor_guid, vendor, sizeof(*vendor)); > + call.u.set_variable.size = data_size; > + set_xen_guest_handle(call.u.set_variable.data, data); > + > + return HYPERVISOR_platform_op(&op) ? EFI_UNSUPPORTED : call.status; > +} > + > +static efi_status_t xen_efi_get_next_high_mono_count(u32 *count) > +{ > + int err; > + DECLARE_CALL(get_next_high_monotonic_count); > + > + err = HYPERVISOR_platform_op(&op); > + if (err) > + return EFI_UNSUPPORTED; > + > + *count = call.misc; > + > + return call.status; > +} > + > +#undef DECLARE_CALL > +#undef call > + > +struct efi __read_mostly efi = { > + .mps = EFI_INVALID_TABLE_ADDR, > + .acpi = EFI_INVALID_TABLE_ADDR, > + .acpi20 = EFI_INVALID_TABLE_ADDR, > + .smbios = EFI_INVALID_TABLE_ADDR, > + .sal_systab = EFI_INVALID_TABLE_ADDR, > + .boot_info = EFI_INVALID_TABLE_ADDR, > + .hcdp = EFI_INVALID_TABLE_ADDR, > + .uga = EFI_INVALID_TABLE_ADDR, > + .uv_systab = EFI_INVALID_TABLE_ADDR, > + .get_time = xen_efi_get_time, > + .set_time = xen_efi_set_time, > + .get_wakeup_time = xen_efi_get_wakeup_time, > + .set_wakeup_time = xen_efi_set_wakeup_time, > + .get_variable = xen_efi_get_variable, > + .get_next_variable = xen_efi_get_next_variable, > + .set_variable = xen_efi_set_variable, > + .get_next_high_mono_count = xen_efi_get_next_high_mono_count, > +}; > +EXPORT_SYMBOL(efi); > + > +static int __init setup_noefi(char *arg) > +{ > + efi_enabled = 0; > + return 0; > +} > +early_param("noefi", setup_noefi); > + > + > +int efi_set_rtc_mmss(unsigned long nowtime) > +{ > + int real_seconds, real_minutes; > + efi_status_t status; > + efi_time_t eft; > + efi_time_cap_t cap; > + > + status = efi.get_time(&eft, &cap); > + if (status != EFI_SUCCESS) { > + printk(KERN_ERR "Oops: efitime: can't read time!\n"); > + return -1; > + } > + > + real_seconds = nowtime % 60; > + real_minutes = nowtime / 60; > + if (((abs(real_minutes - eft.minute) + 15)/30) & 1) > + real_minutes += 30; > + real_minutes %= 60; > + eft.minute = real_minutes; > + eft.second = real_seconds; > + > + status = efi.set_time(&eft); > + if (status != EFI_SUCCESS) { > + printk(KERN_ERR "Oops: efitime: can't write time!\n"); > + return -1; > + } > + return 0; > +} > + > +unsigned long efi_get_time(void) > +{ > + efi_status_t status; > + efi_time_t eft; > + efi_time_cap_t cap; > + > + status = efi.get_time(&eft, &cap); > + if (status != EFI_SUCCESS) { > + printk(KERN_ERR "Oops: efitime: can't read time!\n"); > + return mach_get_cmos_time(); > + } > + > + return mktime(eft.year, eft.month, eft.day, eft.hour, > + eft.minute, eft.second); > +} > + > +void __init efi_probe(void) > +{ > + static struct xen_platform_op __initdata op = { > + .cmd = XENPF_firmware_info, > + .u.firmware_info = { > + .type = XEN_FW_EFI_INFO, > + .index = XEN_FW_EFI_CONFIG_TABLE > + } > + }; > + > + if (HYPERVISOR_platform_op(&op) == 0) > + efi_enabled = 1; > +} > + > +void __init efi_init(void) > +{ > + efi_config_table_t *config_tables; > + efi_char16_t c16[100]; > + char vendor[ARRAY_SIZE(c16)] = "unknown"; > + int ret, i; > + struct xen_platform_op op; > + union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info; > + > + op.cmd = XENPF_firmware_info; > + op.u.firmware_info.type = XEN_FW_EFI_INFO; > + > + /* > + * Show what we know for posterity > + */ > + op.u.firmware_info.index = XEN_FW_EFI_VENDOR; > + info->vendor.bufsz = sizeof(c16); > + set_xen_guest_handle(info->vendor.name, c16); > + ret = HYPERVISOR_platform_op(&op); > + if (!ret) { > + for (i = 0; i < sizeof(vendor) - 1 && c16[i]; ++i) > + vendor[i] = c16[i]; > + vendor[i] = '\0'; > + } else > + printk(KERN_ERR PFX "Could not get the firmware vendor!\n"); > + > + op.u.firmware_info.index = XEN_FW_EFI_VERSION; > + ret = HYPERVISOR_platform_op(&op); > + if (!ret) > + printk(KERN_INFO "EFI v%u.%.02u by %s\n", > + info->version >> 16, > + info->version & 0xffff, vendor); > + else > + printk(KERN_ERR PFX "Could not get EFI revision!\n"); > + > + /* > + * Let's see what config tables the firmware passed to us. > + */ > + op.u.firmware_info.index = XEN_FW_EFI_CONFIG_TABLE; > + if (HYPERVISOR_platform_op(&op)) > + BUG(); > + config_tables = early_ioremap( > + info->cfg.addr, > + info->cfg.nent * sizeof(efi_config_table_t)); > + if (config_tables == NULL) > + panic("Could not map EFI Configuration Table!\n"); > + > + printk(KERN_INFO); > + for (i = 0; i < info->cfg.nent; i++) { > + if (!efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID)) { > + efi.mps = config_tables[i].table; > + printk(" MPS=0x%lx ", config_tables[i].table); > + } else if (!efi_guidcmp(config_tables[i].guid, > + ACPI_20_TABLE_GUID)) { > + efi.acpi20 = config_tables[i].table; > + printk(" ACPI 2.0=0x%lx ", config_tables[i].table); > + } else if (!efi_guidcmp(config_tables[i].guid, > + ACPI_TABLE_GUID)) { > + efi.acpi = config_tables[i].table; > + printk(" ACPI=0x%lx ", config_tables[i].table); > + } else if (!efi_guidcmp(config_tables[i].guid, > + SMBIOS_TABLE_GUID)) { > + efi.smbios = config_tables[i].table; > + printk(" SMBIOS=0x%lx ", config_tables[i].table); > + } else if (!efi_guidcmp(config_tables[i].guid, > + HCDP_TABLE_GUID)) { > + efi.hcdp = config_tables[i].table; > + printk(" HCDP=0x%lx ", config_tables[i].table); > + } else if (!efi_guidcmp(config_tables[i].guid, > + UGA_IO_PROTOCOL_GUID)) { > + efi.uga = config_tables[i].table; > + printk(" UGA=0x%lx ", config_tables[i].table); > + } > + } > + printk("\n"); > + early_iounmap(config_tables, info->cfg.nent * sizeof(efi_config_table_t)); > + > + x86_platform.get_wallclock = efi_get_time; > + x86_platform.set_wallclock = efi_set_rtc_mmss; > +} > + > +void __init efi_enter_virtual_mode(void) { } > + > +static struct platform_device rtc_efi_dev = { > + .name = "rtc-efi", > + .id = -1, > +}; > + > +static int __init rtc_init(void) > +{ > + if (efi_enabled && platform_device_register(&rtc_efi_dev) < 0) > + printk(KERN_ERR "unable to register rtc device...\n"); > + > + /* not necessarily an error */ > + return 0; > +} > +arch_initcall(rtc_init); > + > +/* > + * Convenience functions to obtain memory types and attributes > + */ > +u32 efi_mem_type(unsigned long phys_addr) > +{ > + struct xen_platform_op op; > + union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info; > + > + op.cmd = XENPF_firmware_info; > + op.u.firmware_info.type = XEN_FW_EFI_INFO; > + op.u.firmware_info.index = XEN_FW_EFI_MEM_INFO; > + info->mem.addr = phys_addr; > + info->mem.size = 0; > + return HYPERVISOR_platform_op(&op) ? 0 : info->mem.type; > +} > + > +u64 efi_mem_attributes(unsigned long phys_addr) > +{ > + struct xen_platform_op op; > + union xenpf_efi_info *info = &op.u.firmware_info.u.efi_info; > + > + op.cmd = XENPF_firmware_info; > + op.u.firmware_info.type = XEN_FW_EFI_INFO; > + op.u.firmware_info.index = XEN_FW_EFI_MEM_INFO; > + info->mem.addr = phys_addr; > + info->mem.size = 0; > + return HYPERVISOR_platform_op(&op) ? 0 : info->mem.attr; > +} > --- head-2011-05-23.orig/drivers/rtc/Kconfig 2011-06-21 15:35:45.000000000 > +0200 > +++ head-2011-05-23/drivers/rtc/Kconfig 2011-06-21 15:06:11.000000000 +0200 > @@ -522,7 +522,7 @@ config RTC_DRV_DS1742 > > config RTC_DRV_EFI > tristate "EFI RTC" > - depends on IA64 > + depends on IA64 || (XEN && EFI) > help > If you say yes here you will get support for the EFI > Real Time Clock. > --- head-2011-05-23.orig/drivers/xen/console/console.c 2011-06-21 > 15:35:45.000000000 +0200 > +++ head-2011-05-23/drivers/xen/console/console.c 2011-06-15 > 15:41:36.000000000 +0200 > @@ -315,6 +315,7 @@ void __init dom0_init_screen_info(const > break; > > case XEN_VGATYPE_VESA_LFB: > + case XEN_VGATYPE_EFI_LFB: > if (size < offsetof(struct dom0_vga_console_info, > u.vesa_lfb.gbl_caps)) > break; > @@ -333,6 +334,10 @@ void __init dom0_init_screen_info(const > screen_info.blue_pos = info->u.vesa_lfb.blue_pos; > screen_info.rsvd_size = info->u.vesa_lfb.rsvd_size; > screen_info.rsvd_pos = info->u.vesa_lfb.rsvd_pos; > + if (info->video_type == XEN_VGATYPE_EFI_LFB) { > + screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; > + break; > + } > if (size >= offsetof(struct dom0_vga_console_info, > u.vesa_lfb.gbl_caps) > + sizeof(info->u.vesa_lfb.gbl_caps)) > --- head-2011-05-23.orig/include/linux/efi.h 2011-06-21 15:35:45.000000000 > +0200 > +++ head-2011-05-23/include/linux/efi.h 2011-06-10 11:12:39.000000000 +0200 > @@ -249,7 +249,9 @@ struct efi_memory_map { > * All runtime access to EFI goes through this structure: > */ > extern struct efi { > +#ifndef CONFIG_XEN > efi_system_table_t *systab; /* EFI system table */ > +#endif > unsigned long mps; /* MPS table */ > unsigned long acpi; /* ACPI table (IA64 ext 0.71) */ > unsigned long acpi20; /* ACPI table (ACPI 2.0) */ > @@ -267,8 +269,10 @@ extern struct efi { > efi_get_next_variable_t *get_next_variable; > efi_set_variable_t *set_variable; > efi_get_next_high_mono_count_t *get_next_high_mono_count; > +#ifndef CONFIG_XEN > efi_reset_system_t *reset_system; > efi_set_virtual_address_map_t *set_virtual_address_map; > +#endif > } efi; > > static inline int > --- head-2011-05-23.orig/include/xen/interface/platform.h 2011-06-21 > 15:35:45.000000000 +0200 > +++ head-2011-05-23/include/xen/interface/platform.h 2011-06-17 > 16:07:28.000000000 +0200 > @@ -114,10 +114,86 @@ struct xenpf_platform_quirk { > typedef struct xenpf_platform_quirk xenpf_platform_quirk_t; > DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t); > > +#define XENPF_efi_runtime_call 49 > +#define XEN_EFI_get_time 1 > +#define XEN_EFI_set_time 2 > +#define XEN_EFI_get_wakeup_time 3 > +#define XEN_EFI_set_wakeup_time 4 > +#define XEN_EFI_get_next_high_monotonic_count 5 > +#define XEN_EFI_get_variable 6 > +#define XEN_EFI_set_variable 7 > +#define XEN_EFI_get_next_variable_name 8 > +struct xenpf_efi_runtime_call { > + uint32_t function; > + /* > + * This field is generally used for per sub-function flags (defined > + * below), except for the XEN_EFI_get_next_high_monotonic_count case, > + * where it holds the single returned value. > + */ > + uint32_t misc; > + unsigned long status; > + union { > +#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x00000001 > + struct { > + struct xenpf_efi_time { > + uint16_t year; > + uint8_t month; > + uint8_t day; > + uint8_t hour; > + uint8_t min; > + uint8_t sec; > + uint32_t ns; > + int16_t tz; > + uint8_t daylight; > + } time; > + uint32_t resolution; > + uint32_t accuracy; > + } get_time; > + > + struct xenpf_efi_time set_time; > + > +#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x00000001 > +#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x00000002 > + struct xenpf_efi_time get_wakeup_time; > + > +#define XEN_EFI_SET_WAKEUP_TIME_ENABLE 0x00000001 > +#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x00000002 > + struct xenpf_efi_time set_wakeup_time; > + > +#define XEN_EFI_VARIABLE_NON_VOLATILE 0x00000001 > +#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 > +#define XEN_EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 > + struct { > + XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ > + unsigned long size; > + XEN_GUEST_HANDLE(void) data; > + struct xenpf_efi_guid { > + uint32_t data1; > + uint16_t data2; > + uint16_t data3; > + uint8_t data4[8]; > + } vendor_guid; > + } get_variable, set_variable; > + > + struct { > + unsigned long size; > + XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ > + struct xenpf_efi_guid vendor_guid; > + } get_next_variable_name; > + } u; > +}; > +typedef struct xenpf_efi_runtime_call xenpf_efi_runtime_call_t; > +DEFINE_XEN_GUEST_HANDLE(xenpf_efi_runtime_call_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 */ > #define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */ > +#define XEN_FW_EFI_INFO 4 /* from EFI */ > +#define XEN_FW_EFI_VERSION 0 > +#define XEN_FW_EFI_CONFIG_TABLE 1 > +#define XEN_FW_EFI_VENDOR 2 > +#define XEN_FW_EFI_MEM_INFO 3 > struct xenpf_firmware_info { > /* IN variables. */ > uint32_t type; > @@ -148,6 +224,24 @@ struct xenpf_firmware_info { > /* must refer to 128-byte buffer */ > XEN_GUEST_HANDLE(uint8) edid; > } vbeddc_info; /* XEN_FW_VBEDDC_INFO */ > + union xenpf_efi_info { > + uint32_t version; > + struct { > + uint64_t addr; /* EFI_CONFIGURATION_TABLE */ > + uint32_t nent; > + } cfg; > + struct { > + uint32_t revision; > + uint32_t bufsz; /* input, in bytes */ > + XEN_GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ > + } vendor; > + struct { > + uint64_t addr; > + uint64_t size; > + uint64_t attr; > + uint32_t type; > + } mem; > + } efi_info; /* XEN_FW_EFI_INFO */ > } u; > }; > typedef struct xenpf_firmware_info xenpf_firmware_info_t; > @@ -373,6 +467,7 @@ struct xen_platform_op { > struct xenpf_read_memtype read_memtype; > struct xenpf_microcode_update microcode; > struct xenpf_platform_quirk platform_quirk; > + struct xenpf_efi_runtime_call efi_runtime_call; > struct xenpf_firmware_info firmware_info; > struct xenpf_enter_acpi_sleep enter_acpi_sleep; > struct xenpf_change_freq change_freq; > --- head-2011-05-23.orig/include/xen/interface/xen.h 2011-06-21 > 15:35:45.000000000 +0200 > +++ head-2011-05-23/include/xen/interface/xen.h 2011-06-07 13:55:11.000000000 > +0200 > @@ -660,6 +660,7 @@ typedef struct dom0_vga_console_info { > uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */ > #define XEN_VGATYPE_TEXT_MODE_3 0x03 > #define XEN_VGATYPE_VESA_LFB 0x23 > +#define XEN_VGATYPE_EFI_LFB 0x70 > > union { > struct { > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |