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-devel

Re: [Xen-devel] [PATCH 3/4] x86-64: EFI runtime code

To: Jan Beulich <JBeulich@xxxxxxxxxx>, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH 3/4] x86-64: EFI runtime code
From: Keir Fraser <keir.xen@xxxxxxxxx>
Date: Tue, 28 Jun 2011 08:39:58 +0100
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 28 Jun 2011 00:41:17 -0700
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:user-agent:date:subject:from:to:cc:message-id :thread-topic:thread-index:in-reply-to:mime-version:content-type :content-transfer-encoding; bh=6ybrMLr5Z8T+kXTIQc/uu2gqegHT+5yU//ErubK3YDQ=; b=RbtN070mtWOW/MHFOEqwK4UGIMoLioG+1VHcFd/h0/cwTQ53cu9fRS1CWDfHrS3zM6 F4VhwtpIbx+rozmg7RTFCK6rqpUcEOshDD9N31IyFTsRyYrFQ5WVDXuRm5tzwKMxpg5p SjBxmxUcgTAHmsA6r7YLRfCBNdDl5Ca0lj0gA=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=user-agent:date:subject:from:to:cc:message-id:thread-topic :thread-index:in-reply-to:mime-version:content-type :content-transfer-encoding; b=bLprsecarzkDj+WOpwMFyJO4U9TDyLFRTrL6gCPf5hqdipr6c5/RxWBbcMQ0lAtiaW Hg5HIeD/tpkBQEzPZ5x7hdUHfytaKpE3+7SoxMA42rCc5aiPSuTmzzqUvne2RjDVCoiW VrAqNocCVP7YJu3yN+bVCIQII6NrOf0KYAFME=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4E099AA6020000780004A4C6@xxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acw1ZpRssGzaxx/CrkSO5uGdOxD77Q==
Thread-topic: [Xen-devel] [PATCH 3/4] x86-64: EFI runtime code
User-agent: Microsoft-Entourage/12.29.0.110113
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