Bei Guan
2011-Jul-22 16:27 UTC
[Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
# HG changeset patch # User gbtju85@gmail.com # Xen: Expose hvmloader/bios in libxl and xend. Exposes the hvmloader/bios xenstore key in libxl and xend, so firmware loaded can be overriden (choices: rombios, seabios ovmf-ia32, ovmf-x64). Sign-off-by: Bei Guan <gbtju85@gmail.com> diff -r e298ce67777e tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/libxl/libxl.idl Fri Jul 22 23:00:20 2011 +0800 @@ -137,6 +137,7 @@ libxl_domain_create_info = Struct("domain_create_info",[ ("hvm", bool), + ("hvmbios", string), ("hap", bool), ("oos", bool), ("ssidref", uint32), diff -r e298ce67777e tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/libxl/libxl_create.c Fri Jul 22 23:00:20 2011 +0800 @@ -377,6 +377,10 @@ if (info->poolname) xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); + if (info->hvmbios){ + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", dom_path), info->hvmbios, strlen(info->hvmbios)); + } + libxl__xs_writev(gc, t, dom_path, info->xsdata); libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), info->platformdata); diff -r e298ce67777e tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/libxl/libxl_dm.c Fri Jul 22 23:00:20 2011 +0800 @@ -783,6 +783,7 @@ char *vm_path; char **pass_stuff; const char *dm; + char *custom_bios; if (info->device_model_stubdomain) { libxl_device_vfb vfb; @@ -814,10 +815,13 @@ goto out; } - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); - xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), - "%s", libxl__domain_bios(gc, info)); + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/hvmloader/bios", info->domid)); + if (!custom_bios) { + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); + xs_mkdir(ctx->xsh, XBT_NULL, path); + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), + "%s", libxl__domain_bios(gc, info)); + } path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path); diff -r e298ce67777e tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/libxl/xl_cmdimpl.c Fri Jul 22 23:00:20 2011 +0800 @@ -553,6 +553,10 @@ } } + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ + c_info->hvmbios = strdup(buf); + } + c_info->hvm = 0; if (!xlu_cfg_get_string (config, "builder", &buf) && !strncmp(buf, "hvm", strlen(buf))) diff -r e298ce67777e tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/python/xen/xend/XendConfig.py Fri Jul 22 23:00:20 2011 +0800 @@ -153,6 +153,7 @@ ''fdb'': str, ''keymap'': str, ''isa'' : int, + ''hvmbios'' : str, ''localtime'': int, ''monitor'': int, ''monitor_path'': str, diff -r e298ce67777e tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Jul 22 23:00:20 2011 +0800 @@ -1789,6 +1789,10 @@ if self.info.has_key(''security_label''): f(''security_label'', self.info[''security_label'']) + hvm = self.info.is_hvm() + if hvm and self.info["platform"].get("hvmbios") is not None: + f(''hvmloader/bios'', self.info["platform"].get("hvmbios")) + to_store.update(self._vcpuDomDetails()) log.debug("Storing domain details: %s", scrub_password(to_store)) diff -r e298ce67777e tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/python/xen/xm/create.py Fri Jul 22 23:00:20 2011 +0800 @@ -168,6 +168,10 @@ fn=set_value, default=None, use="Path to kernel image.") +gopts.var(''hvmbios'', val=''HVMBIOS'', + fn=set_value, default=None, + use="Type of firmware to load in HVM mode") + gopts.var(''ramdisk'', val=''FILE'', fn=set_value, default='''', use="Path to ramdisk.") @@ -1084,7 +1088,7 @@ ''device_model'', ''display'', ''fda'', ''fdb'', ''gfx_passthru'', ''guest_os_type'', - ''hap'', ''hpet'', + ''hap'', ''hpet'', ''hvmbios'', ''isa'', ''keymap'', ''localtime'', @@ -1143,7 +1147,7 @@ ''on_reboot'', ''on_crash'', ''features'', ''on_xend_start'', ''on_xend_stop'', ''target'', ''cpuid'', ''cpuid_check'', ''machine_address_size'', ''suppress_spurious_page_faults'', - ''description'']) + ''description'' ]) vcpu_conf() if vals.uuid is not None: diff -r e298ce67777e tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/python/xen/xm/xenapi_create.py Fri Jul 22 23:00:20 2011 +0800 @@ -1090,6 +1090,7 @@ ''fda'', ''fdb'', ''keymap'', + ''hvmbios'', ''isa'', ''localtime'', ''monitor'', _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-22 16:44 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 22/07/2011 17:27, "Bei Guan" <gbtju85@gmail.com> wrote:> # HG changeset patch > # User gbtju85@gmail.com > # > > Xen: Expose hvmloader/bios in libxl and xend. > > Exposes the hvmloader/bios xenstore key in libxl and xend, > so firmware loaded can be overriden (choices: rombios, seabios > ovmf-ia32, ovmf-x64).There''s already some BIOS-configuration logic in libxl (see libxl__domain_bios()) which I would assume you hook up to. Ian Campbell would know better -- he wrote it. I''d probably prefer to let xend grow obsolete quietly than add further features. Noone''s maintaining it to fix it up if new features break it. No strong opinion on that though, it''s up to the tools maintainers. -- Keir> Sign-off-by: Bei Guan <gbtju85@gmail.com> > > diff -r e298ce67777e tools/libxl/libxl.idl > --- a/tools/libxl/libxl.idl Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/libxl/libxl.idl Fri Jul 22 23:00:20 2011 +0800 > @@ -137,6 +137,7 @@ > > libxl_domain_create_info = Struct("domain_create_info",[ > ("hvm", bool), > + ("hvmbios", string), > ("hap", bool), > ("oos", bool), > ("ssidref", uint32), > diff -r e298ce67777e tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/libxl/libxl_create.c Fri Jul 22 23:00:20 2011 +0800 > @@ -377,6 +377,10 @@ > if (info->poolname) > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), > info->poolname, strlen(info->poolname)); > > + if (info->hvmbios){ > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", > dom_path), info->hvmbios, strlen(info->hvmbios)); > + } > + > libxl__xs_writev(gc, t, dom_path, info->xsdata); > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), > info->platformdata); > > diff -r e298ce67777e tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/libxl/libxl_dm.c Fri Jul 22 23:00:20 2011 +0800 > @@ -783,6 +783,7 @@ > char *vm_path; > char **pass_stuff; > const char *dm; > + char *custom_bios; > > if (info->device_model_stubdomain) { > libxl_device_vfb vfb; > @@ -814,10 +815,13 @@ > goto out; > } > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > - xs_mkdir(ctx->xsh, XBT_NULL, path); > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > - "%s", libxl__domain_bios(gc, info)); > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, > "/local/domain/%d/hvmloader/bios", info->domid)); > + if (!custom_bios) { > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > + xs_mkdir(ctx->xsh, XBT_NULL, path); > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > + "%s", libxl__domain_bios(gc, info)); > + } > > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", > info->domid); > xs_mkdir(ctx->xsh, XBT_NULL, path); > diff -r e298ce67777e tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/libxl/xl_cmdimpl.c Fri Jul 22 23:00:20 2011 +0800 > @@ -553,6 +553,10 @@ > } > } > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > + c_info->hvmbios = strdup(buf); > + } > + > c_info->hvm = 0; > if (!xlu_cfg_get_string (config, "builder", &buf) && > !strncmp(buf, "hvm", strlen(buf))) > diff -r e298ce67777e tools/python/xen/xend/XendConfig.py > --- a/tools/python/xen/xend/XendConfig.py Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/python/xen/xend/XendConfig.py Fri Jul 22 23:00:20 2011 +0800 > @@ -153,6 +153,7 @@ > ''fdb'': str, > ''keymap'': str, > ''isa'' : int, > + ''hvmbios'' : str, > ''localtime'': int, > ''monitor'': int, > ''monitor_path'': str, > diff -r e298ce67777e tools/python/xen/xend/XendDomainInfo.py > --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jul 18 14:38:31 2011 > +0100 > +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Jul 22 23:00:20 2011 > +0800 > @@ -1789,6 +1789,10 @@ > if self.info.has_key(''security_label''): > f(''security_label'', self.info <http://self.info> > [''security_label'']) > > + hvm = self.info.is_hvm() > + if hvm and self.info <http://self.info> ["platform"].get("hvmbios") > is not None: > + f(''hvmloader/bios'', self.info <http://self.info> > ["platform"].get("hvmbios")) > + > to_store.update(self._vcpuDomDetails()) > > log.debug("Storing domain details: %s", scrub_password(to_store)) > diff -r e298ce67777e tools/python/xen/xm/create.py > --- a/tools/python/xen/xm/create.py Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/python/xen/xm/create.py Fri Jul 22 23:00:20 2011 +0800 > @@ -168,6 +168,10 @@ > fn=set_value, default=None, > use="Path to kernel image.") > > +gopts.var(''hvmbios'', val=''HVMBIOS'', > + fn=set_value, default=None, > + use="Type of firmware to load in HVM mode") > + > gopts.var(''ramdisk'', val=''FILE'', > fn=set_value, default='''', > use="Path to ramdisk.") > @@ -1084,7 +1088,7 @@ > ''device_model'', ''display'', > ''fda'', ''fdb'', > ''gfx_passthru'', ''guest_os_type'', > - ''hap'', ''hpet'', > + ''hap'', ''hpet'', ''hvmbios'', > ''isa'', > ''keymap'', > ''localtime'', > @@ -1143,7 +1147,7 @@ > ''on_reboot'', ''on_crash'', ''features'', ''on_xend_start'', > ''on_xend_stop'', ''target'', ''cpuid'', ''cpuid_check'', > ''machine_address_size'', ''suppress_spurious_page_faults'', > - ''description'']) > + ''description'' ]) > > vcpu_conf() > if vals.uuid is not None: > diff -r e298ce67777e tools/python/xen/xm/xenapi_create.py > --- a/tools/python/xen/xm/xenapi_create.py Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/python/xen/xm/xenapi_create.py Fri Jul 22 23:00:20 2011 +0800 > @@ -1090,6 +1090,7 @@ > ''fda'', > ''fdb'', > ''keymap'', > + ''hvmbios'', > ''isa'', > ''localtime'', > ''monitor'', > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Aug-04 15:38 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Keir Fraser writes ("Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM"):> I''d probably prefer to let xend grow obsolete quietly than add further > features. Noone''s maintaining it to fix it up if new features break it. No > strong opinion on that though, it''s up to the tools maintainers.I would agree. I would want a compelling reason (or strong community support) to accept new feature patches to xend. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Bei Guan
2011-Aug-05 11:20 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Hi All, Thank you for all your comments. I has removed the patch for xend and modified some other little stuff according to your comments. I have rebased my patches on the top of the latest Xen-unstable version (changeset: 23756:0f36c2eec2e). Is there any more comment? Thank you very much. In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is copied form method pci_setup() in hvmloader/pci.c except for all the VGA related stuff. This method is assigned to bios->pci_setup(). The reason for adding such a method is stated here: http://sourceforge.net/mailarchive/message.php?msg_id=27854247 The patches are also available at https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_support.patch https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.patch https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmware.patch # HG changeset patch # User gbtju85@gmail.com # Enable Xen-unstable hvmloader to load OVMF BIOS. It supports OVMF BIOS in IA32 and X86 environment. Usage: Add an option field in HVM config file. # OVMF support. When enabled, hvmloader can load OVMF bios of IA32("ovmf-ia32") and X64("ovmf-x64") hvmbios = "ovmf-ia32" #hvmbios = "ovmf-x64" Note: Enable the HVM guest ACPI: acpi=1 Use the OVMF to boot into a UEFI-aware OS, such as ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 @@ -43,6 +43,19 @@ CFLAGS += -DENABLE_ROMBIOS ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest endif +OVMF_DIR := ../ovmf +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin + +ifneq ($(OVMF32_ROM),) +OBJS += ovmf.o +endif + +ifneq ($(OVMF64_ROM),) +OBJS += ovmf.o +endif ifneq ($(SEABIOS_DIR),) OBJS += seabios.o @@ -69,7 +82,7 @@ $(OBJCOPY) hvmloader.tmp hvmloader rm -f hvmloader.tmp -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) ../etherboot/eb-roms.h +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) ../etherboot/eb-roms.h echo "/* Autogenerated file. DO NOT EDIT */" > $@.new ifneq ($(ROMBIOS_ROM),) @@ -84,6 +97,30 @@ echo "#endif" >> $@.new endif +ifneq ($(OVMF32_ROM),) + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new + echo "#endif" >> $@.new +endif + +ifneq ($(OVMF64_ROM),) + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new + echo "#endif" >> $@.new +endif + +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new + echo "#endif" >> $@.new +endif + +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new + echo "#endif" >> $@.new +endif + ifneq ($(STDVGA_ROM),) echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 @@ -3,7 +3,7 @@ #include <stdint.h> -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; extern enum virtual_vga virtual_vga; struct bios_config { @@ -27,6 +27,7 @@ void (*vm86_setup)(void); void (*e820_setup)(void); + void (*pci_setup)(void); void (*acpi_build_tables)(void); void (*create_mp_tables)(void); @@ -36,6 +37,8 @@ extern struct bios_config rombios_config; extern struct bios_config seabios_config; +extern struct bios_config ovmf32_config; +extern struct bios_config ovmf64_config; #define PAGE_SHIFT 12 #define PAGE_SIZE (1ul << PAGE_SHIFT) diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 @@ -361,6 +361,8 @@ #ifdef ENABLE_SEABIOS { "seabios", &seabios_config, }, #endif + { "ovmf-ia32", &ovmf32_config, }, + { "ovmf-x64", &ovmf64_config, }, { NULL, NULL } }; @@ -420,7 +422,11 @@ printf("CPU speed is %u MHz\n", get_cpu_mhz()); apic_setup(); - pci_setup(); + if (bios->pci_setup) { + bios->pci_setup(); + } else { + pci_setup(); + } smp_initialise(); @@ -471,6 +477,8 @@ vgabios_sz = round_option_rom( (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); break; + case VGA_custom: + break; default: printf("No emulated VGA adaptor ...\n"); break; diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800 @@ -0,0 +1,394 @@ +/* + * HVM OVMF UEFI support. + * + * Bei Guan, gbtju85@gmail.com + * Andrei Warkentin, andreiw@motorola.com + * Leendert van Doorn, leendert@watson.ibm.com + * Copyright (c) 2005, International Business Machines Corporation. + * Copyright (c) 2006, Keir Fraser, XenSource Inc. + * Copyright (c) 2011, Citrix Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "config.h" +#include "smbios_types.h" +#include "acpi/acpi2_0.h" +#include "apic_regs.h" +#include "../rombios/config.h" +#include "util.h" +#include "pci_regs.h" +#include "hypercall.h" + +#include <xen/hvm/params.h> +#include <xen/hvm/ioreq.h> +#include <xen/memory.h> + +#define ROM_INCLUDE_OVMF32 +#define ROM_INCLUDE_OVMF64 +#define ROM_INCLUDE_OVMF32_CIRRUS_VGA +#define ROM_INCLUDE_OVMF64_CIRRUS_VGA +#include "roms.inc" + +#define OVMF_BEGIN 0xFFF00000ULL +#define OVMF_SIZE 0x00100000ULL +#define OVMF_MAXOFFSET 0x000FFFFFULL +#define OVMF_END (OVMF_BEGIN + OVMF_SIZE) +#define LOWCHUNK_BEGIN 0x000F0000 +#define LOWCHUNK_SIZE 0x00010000 +#define LOWCHUNK_MAXOFFSET 0x0000FFFF +#define LOWCHUNK_END (OVMF_BEGIN + OVMF_SIZE) + +/* + * Set up an empty TSS area for virtual 8086 mode to use. + * The only important thing is that it musn''t have any bits set + * in the interrupt redirection bitmap, so all zeros will do. + */ +static void ovmf_init_vm86_tss(void) +{ + void *tss; + struct xen_hvm_param p; + + tss = mem_alloc(128, 128); + memset(tss, 0, 128); + p.domid = DOMID_SELF; + p.index = HVM_PARAM_VM86_TSS; + p.value = virt_to_phys(tss); + hypercall_hvm_op(HVMOP_set_param, &p); + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); +} + +static void ovmf_load(const struct bios_config *config) +{ + xen_pfn_t mfn; + uint64_t addr = OVMF_BEGIN; + + virtual_vga = VGA_custom; + + /* Copy video ROM. */ + if (config == &ovmf32_config) { + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, + ovmf32_cirrus_vga, sizeof(ovmf32_cirrus_vga)); + printf("OVMF32 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf32_cirrus_vga)); + } else if (config == &ovmf64_config) { + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, + ovmf64_cirrus_vga, sizeof(ovmf64_cirrus_vga)); + printf("OVMF64 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf64_cirrus_vga)); + } + + /* Copy low-reset vector portion. */ + memcpy((void *) LOWCHUNK_BEGIN, (uint8_t *) config->image + + OVMF_SIZE + - LOWCHUNK_SIZE, + LOWCHUNK_SIZE); + + /* Ensure we have backing page prior to moving FD. */ + while ((addr >> PAGE_SHIFT) != (OVMF_END >> PAGE_SHIFT)) { + mfn = (uint32_t) (addr >> PAGE_SHIFT); + addr += PAGE_SIZE; + + mem_hole_populate_ram(mfn, 1); + } + + printf("Initialized FD backing pages...\n"); + + /* Copy FD. */ + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); + printf("Load complete!\n"); +} + +/* + * Ideally this function should just adjust the low memory size so MMIO fits, + * everything else should be done in UEFI code + */ +static void ovmf_pci_setup(void) +{ + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; + uint16_t class, vendor_id, device_id; + unsigned int bar, pin, link, isa_irq; + + /* Resources assignable to PCI devices via BARs. */ + struct resource { + uint32_t base, max; + } *resource, mem_resource, io_resource; + + /* Create a list of device BARs in descending order of size. */ + struct bars { + uint32_t devfn, bar_reg, bar_sz; + } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS; + unsigned int i, nr_bars = 0; + + /* Program PCI-ISA bridge with appropriate link routes. */ + isa_irq = 0; + for ( link = 0; link < 4; link++ ) + { + do { isa_irq = (isa_irq + 1) & 15; + } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ); + pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); + printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); + } + + /* Program ELCR to match PCI-wired IRQs. */ + outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0)); + outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8)); + + /* Scan the PCI bus and map resources. */ + for ( devfn = 0; devfn < 256; devfn++ ) + { + class = pci_readw(devfn, PCI_CLASS_DEVICE); + vendor_id = pci_readw(devfn, PCI_VENDOR_ID); + device_id = pci_readw(devfn, PCI_DEVICE_ID); + if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) + continue; + + ASSERT((devfn != PCI_ISA_DEVFN) || + ((vendor_id == 0x8086) && (device_id == 0x7000))); + + switch ( class ) + { + case 0x0680: + /* PIIX4 ACPI PM. Special device with special PCI config space. */ + ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); + pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0x22, 0x0000); + pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ + pci_writew(devfn, 0x3d, 0x0001); + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1); + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ + break; + case 0x0101: + if ( vendor_id == 0x8086 ) + { + /* Intel ICHs since PIIX3: enable IDE legacy mode. */ + pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */ + pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */ + } + break; + } + + /* Map the I/O memory and port resources. */ + for ( bar = 0; bar < 7; bar++ ) + { + bar_reg = PCI_BASE_ADDRESS_0 + 4*bar; + if ( bar == 6 ) + bar_reg = PCI_ROM_ADDRESS; + + bar_data = pci_readl(devfn, bar_reg); + pci_writel(devfn, bar_reg, ~0); + bar_sz = pci_readl(devfn, bar_reg); + pci_writel(devfn, bar_reg, bar_data); + if ( bar_sz == 0 ) + continue; + + bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) =+ PCI_BASE_ADDRESS_SPACE_MEMORY) ? + PCI_BASE_ADDRESS_MEM_MASK : + (PCI_BASE_ADDRESS_IO_MASK & 0xffff)); + bar_sz &= ~(bar_sz - 1); + + for ( i = 0; i < nr_bars; i++ ) + if ( bars[i].bar_sz < bar_sz ) + break; + + if ( i != nr_bars ) + memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars)); + + bars[i].devfn = devfn; + bars[i].bar_reg = bar_reg; + bars[i].bar_sz = bar_sz; + + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) =+ PCI_BASE_ADDRESS_SPACE_MEMORY ) + mmio_total += bar_sz; + + nr_bars++; + + /* Skip the upper-half of the address for a 64-bit BAR. */ + if ( (bar_data & (PCI_BASE_ADDRESS_SPACE | + PCI_BASE_ADDRESS_MEM_TYPE_MASK)) =+ (PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64) ) + bar++; + } + + /* Map the interrupt. */ + pin = pci_readb(devfn, PCI_INTERRUPT_PIN); + if ( pin != 0 ) + { + /* This is the barber''s pole mapping used by Xen. */ + link = ((pin - 1) + (devfn >> 3)) & 3; + isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link); + pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq); + printf("pci dev %02x:%x INT%c->IRQ%u\n", + devfn>>3, devfn&7, ''A''+pin-1, isa_irq); + } + + /* Enable bus mastering. */ + cmd = pci_readw(devfn, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER; + pci_writew(devfn, PCI_COMMAND, cmd); + } + + while ( (mmio_total > (pci_mem_end - pci_mem_start)) && + ((pci_mem_start << 1) != 0) ) + pci_mem_start <<= 1; + + while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend ) + { + struct xen_add_to_physmap xatp; + if ( hvm_info->high_mem_pgend == 0 ) + hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT); + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_gmfn; + xatp.idx = --hvm_info->low_mem_pgend; + xatp.gpfn = hvm_info->high_mem_pgend++; + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) + BUG(); + } + + mem_resource.base = pci_mem_start; + mem_resource.max = pci_mem_end; + io_resource.base = 0xc000; + io_resource.max = 0x10000; + + /* Assign iomem and ioport resources in descending order of size. */ + for ( i = 0; i < nr_bars; i++ ) + { + devfn = bars[i].devfn; + bar_reg = bars[i].bar_reg; + bar_sz = bars[i].bar_sz; + + bar_data = pci_readl(devfn, bar_reg); + + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) =+ PCI_BASE_ADDRESS_SPACE_MEMORY ) + { + resource = &mem_resource; + bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK; + } + else + { + resource = &io_resource; + bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; + } + + base = (resource->base + bar_sz - 1) & ~(bar_sz - 1); + bar_data |= base; + base += bar_sz; + + if ( (base < resource->base) || (base > resource->max) ) + { + printf("pci dev %02x:%x bar %02x size %08x: no space for " + "resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz); + continue; + } + + resource->base = base; + + pci_writel(devfn, bar_reg, bar_data); + printf("pci dev %02x:%x bar %02x size %08x: %08x\n", + devfn>>3, devfn&7, bar_reg, bar_sz, bar_data); + + /* Now enable the memory or I/O mapping. */ + cmd = pci_readw(devfn, PCI_COMMAND); + if ( (bar_reg == PCI_ROM_ADDRESS) || + ((bar_data & PCI_BASE_ADDRESS_SPACE) =+ PCI_BASE_ADDRESS_SPACE_MEMORY) ) + cmd |= PCI_COMMAND_MEMORY; + else + cmd |= PCI_COMMAND_IO; + pci_writew(devfn, PCI_COMMAND, cmd); + } +} + +static void ovmf_acpi_build_tables(void) +{ + acpi_build_tables(ACPI_PHYSICAL_ADDRESS); +} + +static void ovmf_create_smbios_tables(void) +{ + hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct smbios_entry_point), + SMBIOS_PHYSICAL_END); +} + +struct bios_config ovmf32_config = { + .name = "OVMF-IA32", + + .image = ovmf32, + .image_size = sizeof(ovmf32), + + .bios_address = 0, + + .load_roms = 0, + + .optionrom_start = 0, + .optionrom_end = 0, + + .bios_load = ovmf_load, + + .bios_info_setup = NULL, + .bios_info_finish = NULL, + + .vm86_setup = ovmf_init_vm86_tss, + .e820_setup = NULL, + .pci_setup = ovmf_pci_setup, + + .acpi_build_tables = ovmf_acpi_build_tables, + .create_mp_tables = NULL, + .create_smbios_tables = ovmf_create_smbios_tables, + .create_pir_tables = NULL, +}; + +struct bios_config ovmf64_config = { + .name = "OVMF-X64", + + .image = ovmf64, + .image_size = sizeof(ovmf64), + + .bios_address = 0, + + .load_roms = 0, + + .optionrom_start = 0, + .optionrom_end = 0, + + .bios_load = ovmf_load, + + .bios_info_setup = NULL, + .bios_info_finish = NULL, + + .vm86_setup = ovmf_init_vm86_tss, + .e820_setup = NULL, + .pci_setup = ovmf_pci_setup, + + .acpi_build_tables = ovmf_acpi_build_tables, + .create_mp_tables = NULL, + .create_smbios_tables = ovmf_create_smbios_tables, + .create_pir_tables = NULL, +}; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin Binary file tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin has changed diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32.bin Binary file tools/firmware/ovmf/ovmf-ia32.bin has changed diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin Binary file tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin has changed diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64.bin Binary file tools/firmware/ovmf/ovmf-x64.bin has changed # HG changeset patch # User gbtju85@gmail.com # Xen: Expose hvmloader/bios in libxl. Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). Sign-off-by: Bei Guan <gbtju85@gmail.com> diff -r 0f36c2eec2e1 tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 @@ -137,6 +137,7 @@ libxl_domain_create_info = Struct("domain_create_info",[ ("type", libxl_domain_type), + ("hvmbios", string), ("hap", bool), ("oos", bool), ("ssidref", uint32), diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 @@ -407,6 +407,10 @@ if (info->poolname) xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); + if (info->hvmbios){ + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", dom_path), info->hvmbios, strlen(info->hvmbios)); + } + libxl__xs_writev(gc, t, dom_path, info->xsdata); libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), info->platformdata); diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 @@ -804,6 +804,7 @@ char *vm_path; char **pass_stuff; const char *dm; + char *custom_bios; if (info->device_model_stubdomain) { libxl_device_vfb vfb; @@ -835,10 +836,13 @@ goto out; } - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); - xs_mkdir(ctx->xsh, XBT_NULL, path); - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), - "%s", libxl__domain_bios(gc, info)); + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/hvmloader/bios", info->domid)); + if (!custom_bios) { + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); + xs_mkdir(ctx->xsh, XBT_NULL, path); + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), + "%s", libxl__domain_bios(gc, info)); + } path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", info->domid); xs_mkdir(ctx->xsh, XBT_NULL, path); diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 @@ -567,6 +567,10 @@ } } + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ + c_info->hvmbios = strdup(buf); + } + c_info->type = LIBXL_DOMAIN_TYPE_PV; if (!xlu_cfg_get_string (config, "builder", &buf) && !strncmp(buf, "hvm", strlen(buf))) Thanks, Bei Guan 2011/8/4 Ian Jackson <Ian.Jackson@eu.citrix.com>> Keir Fraser writes ("Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) > support in Xen-unstable HVM"): > > I''d probably prefer to let xend grow obsolete quietly than add further > > features. Noone''s maintaining it to fix it up if new features break it. > No > > strong opinion on that though, it''s up to the tools maintainers. > > I would agree. I would want a compelling reason (or strong community > support) to accept new feature patches to xend. > > Ian. >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-05 12:10 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 05/08/2011 04:20, "Bei Guan" <gbtju85@gmail.com> wrote:> Hi All, > > Thank you for all your comments. I has removed the patch for xend and modified > some other little stuff according to your comments. > I have rebased my patches on the top of the latest Xen-unstable version > (changeset: 23756:0f36c2eec2e). > Is there any more comment? Thank you very much. > > In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is copied > form method pci_setup() in hvmloader/pci.c except for all the VGA related > stuff. This method is assigned to bios->pci_setup(). The reason for adding > such a method is stated here: > http://sourceforge.net/mailarchive/message.php?msg_id=27854247No, that email thread appears to be confusion. Andrei is saying that a function like pci_setup() does need to be called -- you can''t replace ovmf_pci_setup() with *nothing*. But there''s nothing in that thread that states, or explains why, you can''t just use the generic function pci_setup(), even if it does contain some pointless stuff for OVMF that will get redone when the BIOS takes control. We need that explanation, or just get rid of ovmf_pci_setup() and use the generic pci_setup() like our legacy BIOSes do. -- Keir> The patches are also available at > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_s > upport.patch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.pa > tch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmw > are.patch > > > # HG changeset patch > # User gbtju85@gmail.com > # > > Enable Xen-unstable hvmloader to load OVMF BIOS. > It supports OVMF BIOS in IA32 and X86 environment. > > Usage: > Add an option field in HVM config file. > # OVMF support. When enabled, hvmloader can load OVMF bios of > IA32("ovmf-ia32") and X64("ovmf-x64") > hvmbios = "ovmf-ia32" > #hvmbios = "ovmf-x64" > > Note: > Enable the HVM guest ACPI: acpi=1 > Use the OVMF to boot into a UEFI-aware OS, such as > ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', > ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > @@ -43,6 +43,19 @@ > CFLAGS += -DENABLE_ROMBIOS > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > endif > +OVMF_DIR := ../ovmf > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > + > +ifneq ($(OVMF32_ROM),) > +OBJS += ovmf.o > +endif > + > +ifneq ($(OVMF64_ROM),) > +OBJS += ovmf.o > +endif > > ifneq ($(SEABIOS_DIR),) > OBJS += seabios.o > @@ -69,7 +82,7 @@ > $(OBJCOPY) hvmloader.tmp hvmloader > rm -f hvmloader.tmp > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > ../etherboot/eb-roms.h > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) > ../etherboot/eb-roms.h > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > ifneq ($(ROMBIOS_ROM),) > @@ -84,6 +97,30 @@ > echo "#endif" >> $@.new > endif > > +ifneq ($(OVMF32_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > ifneq ($(STDVGA_ROM),) > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > @@ -3,7 +3,7 @@ > > #include <stdint.h> > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > extern enum virtual_vga virtual_vga; > > struct bios_config { > @@ -27,6 +27,7 @@ > > void (*vm86_setup)(void); > void (*e820_setup)(void); > + void (*pci_setup)(void); > > void (*acpi_build_tables)(void); > void (*create_mp_tables)(void); > @@ -36,6 +37,8 @@ > > extern struct bios_config rombios_config; > extern struct bios_config seabios_config; > +extern struct bios_config ovmf32_config; > +extern struct bios_config ovmf64_config; > > #define PAGE_SHIFT 12 > #define PAGE_SIZE (1ul << PAGE_SHIFT) > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 > @@ -361,6 +361,8 @@ > #ifdef ENABLE_SEABIOS > { "seabios", &seabios_config, }, > #endif > + { "ovmf-ia32", &ovmf32_config, }, > + { "ovmf-x64", &ovmf64_config, }, > { NULL, NULL } > }; > > @@ -420,7 +422,11 @@ > printf("CPU speed is %u MHz\n", get_cpu_mhz()); > > apic_setup(); > - pci_setup(); > + if (bios->pci_setup) { > + bios->pci_setup(); > + } else { > + pci_setup(); > + } > > smp_initialise(); > > @@ -471,6 +477,8 @@ > vgabios_sz = round_option_rom( > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > break; > + case VGA_custom: > + break; > default: > printf("No emulated VGA adaptor ...\n"); > break; > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800 > @@ -0,0 +1,394 @@ > +/* > + * HVM OVMF UEFI support. > + * > + * Bei Guan, gbtju85@gmail.com > + * Andrei Warkentin, andreiw@motorola.com > + * Leendert van Doorn, leendert@watson.ibm.com > + * Copyright (c) 2005, International Business Machines Corporation. > + * Copyright (c) 2006, Keir Fraser, XenSource Inc. > + * Copyright (c) 2011, Citrix Inc. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > with > + * this program; if not, write to the Free Software Foundation, Inc., 59 > Temple > + * Place - Suite 330, Boston, MA 02111-1307 USA. > + */ > + > +#include "config.h" > +#include "smbios_types.h" > +#include "acpi/acpi2_0.h" > +#include "apic_regs.h" > +#include "../rombios/config.h" > +#include "util.h" > +#include "pci_regs.h" > +#include "hypercall.h" > + > +#include <xen/hvm/params.h> > +#include <xen/hvm/ioreq.h> > +#include <xen/memory.h> > + > +#define ROM_INCLUDE_OVMF32 > +#define ROM_INCLUDE_OVMF64 > +#define ROM_INCLUDE_OVMF32_CIRRUS_VGA > +#define ROM_INCLUDE_OVMF64_CIRRUS_VGA > +#include "roms.inc" > + > +#define OVMF_BEGIN 0xFFF00000ULL > +#define OVMF_SIZE 0x00100000ULL > +#define OVMF_MAXOFFSET 0x000FFFFFULL > +#define OVMF_END (OVMF_BEGIN + OVMF_SIZE) > +#define LOWCHUNK_BEGIN 0x000F0000 > +#define LOWCHUNK_SIZE 0x00010000 > +#define LOWCHUNK_MAXOFFSET 0x0000FFFF > +#define LOWCHUNK_END (OVMF_BEGIN + OVMF_SIZE) > + > +/* > + * Set up an empty TSS area for virtual 8086 mode to use. > + * The only important thing is that it musn''t have any bits set > + * in the interrupt redirection bitmap, so all zeros will do. > + */ > +static void ovmf_init_vm86_tss(void) > +{ > + void *tss; > + struct xen_hvm_param p; > + > + tss = mem_alloc(128, 128); > + memset(tss, 0, 128); > + p.domid = DOMID_SELF; > + p.index = HVM_PARAM_VM86_TSS; > + p.value = virt_to_phys(tss); > + hypercall_hvm_op(HVMOP_set_param, &p); > + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > +} > + > +static void ovmf_load(const struct bios_config *config) > +{ > + xen_pfn_t mfn; > + uint64_t addr = OVMF_BEGIN; > + > + virtual_vga = VGA_custom; > + > + /* Copy video ROM. */ > + if (config == &ovmf32_config) { > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > + ovmf32_cirrus_vga, sizeof(ovmf32_cirrus_vga)); > + printf("OVMF32 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf32_cirrus_vga)); > + } else if (config == &ovmf64_config) { > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > + ovmf64_cirrus_vga, sizeof(ovmf64_cirrus_vga)); > + printf("OVMF64 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf64_cirrus_vga)); > + } > + > + /* Copy low-reset vector portion. */ > + memcpy((void *) LOWCHUNK_BEGIN, (uint8_t *) config->image > + + OVMF_SIZE > + - LOWCHUNK_SIZE, > + LOWCHUNK_SIZE); > + > + /* Ensure we have backing page prior to moving FD. */ > + while ((addr >> PAGE_SHIFT) != (OVMF_END >> PAGE_SHIFT)) { > + mfn = (uint32_t) (addr >> PAGE_SHIFT); > + addr += PAGE_SIZE; > + > + mem_hole_populate_ram(mfn, 1); > + } > + > + printf("Initialized FD backing pages...\n"); > + > + /* Copy FD. */ > + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); > + printf("Load complete!\n"); > +} > + > +/* > + * Ideally this function should just adjust the low memory size so MMIO fits, > + * everything else should be done in UEFI code > + */ > +static void ovmf_pci_setup(void) > +{ > + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; > + uint16_t class, vendor_id, device_id; > + unsigned int bar, pin, link, isa_irq; > + > + /* Resources assignable to PCI devices via BARs. */ > + struct resource { > + uint32_t base, max; > + } *resource, mem_resource, io_resource; > + > + /* Create a list of device BARs in descending order of size. */ > + struct bars { > + uint32_t devfn, bar_reg, bar_sz; > + } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS; > + unsigned int i, nr_bars = 0; > + > + /* Program PCI-ISA bridge with appropriate link routes. */ > + isa_irq = 0; > + for ( link = 0; link < 4; link++ ) > + { > + do { isa_irq = (isa_irq + 1) & 15; > + } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ); > + pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); > + printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); > + } > + > + /* Program ELCR to match PCI-wired IRQs. */ > + outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0)); > + outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8)); > + > + /* Scan the PCI bus and map resources. */ > + for ( devfn = 0; devfn < 256; devfn++ ) > + { > + class = pci_readw(devfn, PCI_CLASS_DEVICE); > + vendor_id = pci_readw(devfn, PCI_VENDOR_ID); > + device_id = pci_readw(devfn, PCI_DEVICE_ID); > + if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) > + continue; > + > + ASSERT((devfn != PCI_ISA_DEVFN) || > + ((vendor_id == 0x8086) && (device_id == 0x7000))); > + > + switch ( class ) > + { > + case 0x0680: > + /* PIIX4 ACPI PM. Special device with special PCI config space. > */ > + ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); > + pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ > + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ > + pci_writew(devfn, 0x22, 0x0000); > + pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ > + pci_writew(devfn, 0x3d, 0x0001); > + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1); > + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ > + break; > + case 0x0101: > + if ( vendor_id == 0x8086 ) > + { > + /* Intel ICHs since PIIX3: enable IDE legacy mode. */ > + pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */ > + pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */ > + } > + break; > + } > + > + /* Map the I/O memory and port resources. */ > + for ( bar = 0; bar < 7; bar++ ) > + { > + bar_reg = PCI_BASE_ADDRESS_0 + 4*bar; > + if ( bar == 6 ) > + bar_reg = PCI_ROM_ADDRESS; > + > + bar_data = pci_readl(devfn, bar_reg); > + pci_writel(devfn, bar_reg, ~0); > + bar_sz = pci_readl(devfn, bar_reg); > + pci_writel(devfn, bar_reg, bar_data); > + if ( bar_sz == 0 ) > + continue; > + > + bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY) ? > + PCI_BASE_ADDRESS_MEM_MASK : > + (PCI_BASE_ADDRESS_IO_MASK & 0xffff)); > + bar_sz &= ~(bar_sz - 1); > + > + for ( i = 0; i < nr_bars; i++ ) > + if ( bars[i].bar_sz < bar_sz ) > + break; > + > + if ( i != nr_bars ) > + memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars)); > + > + bars[i].devfn = devfn; > + bars[i].bar_reg = bar_reg; > + bars[i].bar_sz = bar_sz; > + > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY ) > + mmio_total += bar_sz; > + > + nr_bars++; > + > + /* Skip the upper-half of the address for a 64-bit BAR. */ > + if ( (bar_data & (PCI_BASE_ADDRESS_SPACE | > + PCI_BASE_ADDRESS_MEM_TYPE_MASK)) => + (PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_TYPE_64) ) > + bar++; > + } > + > + /* Map the interrupt. */ > + pin = pci_readb(devfn, PCI_INTERRUPT_PIN); > + if ( pin != 0 ) > + { > + /* This is the barber''s pole mapping used by Xen. */ > + link = ((pin - 1) + (devfn >> 3)) & 3; > + isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link); > + pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq); > + printf("pci dev %02x:%x INT%c->IRQ%u\n", > + devfn>>3, devfn&7, ''A''+pin-1, isa_irq); > + } > + > + /* Enable bus mastering. */ > + cmd = pci_readw(devfn, PCI_COMMAND); > + cmd |= PCI_COMMAND_MASTER; > + pci_writew(devfn, PCI_COMMAND, cmd); > + } > + > + while ( (mmio_total > (pci_mem_end - pci_mem_start)) && > + ((pci_mem_start << 1) != 0) ) > + pci_mem_start <<= 1; > + > + while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend ) > + { > + struct xen_add_to_physmap xatp; > + if ( hvm_info->high_mem_pgend == 0 ) > + hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT); > + xatp.domid = DOMID_SELF; > + xatp.space = XENMAPSPACE_gmfn; > + xatp.idx = --hvm_info->low_mem_pgend; > + xatp.gpfn = hvm_info->high_mem_pgend++; > + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > + BUG(); > + } > + > + mem_resource.base = pci_mem_start; > + mem_resource.max = pci_mem_end; > + io_resource.base = 0xc000; > + io_resource.max = 0x10000; > + > + /* Assign iomem and ioport resources in descending order of size. */ > + for ( i = 0; i < nr_bars; i++ ) > + { > + devfn = bars[i].devfn; > + bar_reg = bars[i].bar_reg; > + bar_sz = bars[i].bar_sz; > + > + bar_data = pci_readl(devfn, bar_reg); > + > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY ) > + { > + resource = &mem_resource; > + bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK; > + } > + else > + { > + resource = &io_resource; > + bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; > + } > + > + base = (resource->base + bar_sz - 1) & ~(bar_sz - 1); > + bar_data |= base; > + base += bar_sz; > + > + if ( (base < resource->base) || (base > resource->max) ) > + { > + printf("pci dev %02x:%x bar %02x size %08x: no space for " > + "resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz); > + continue; > + } > + > + resource->base = base; > + > + pci_writel(devfn, bar_reg, bar_data); > + printf("pci dev %02x:%x bar %02x size %08x: %08x\n", > + devfn>>3, devfn&7, bar_reg, bar_sz, bar_data); > + > + /* Now enable the memory or I/O mapping. */ > + cmd = pci_readw(devfn, PCI_COMMAND); > + if ( (bar_reg == PCI_ROM_ADDRESS) || > + ((bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY) ) > + cmd |= PCI_COMMAND_MEMORY; > + else > + cmd |= PCI_COMMAND_IO; > + pci_writew(devfn, PCI_COMMAND, cmd); > + } > +} > + > +static void ovmf_acpi_build_tables(void) > +{ > + acpi_build_tables(ACPI_PHYSICAL_ADDRESS); > +} > + > +static void ovmf_create_smbios_tables(void) > +{ > + hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, > + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct > smbios_entry_point), > + SMBIOS_PHYSICAL_END); > +} > + > +struct bios_config ovmf32_config = { > + .name = "OVMF-IA32", > + > + .image = ovmf32, > + .image_size = sizeof(ovmf32), > + > + .bios_address = 0, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_load = ovmf_load, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + .pci_setup = ovmf_pci_setup, > + > + .acpi_build_tables = ovmf_acpi_build_tables, > + .create_mp_tables = NULL, > + .create_smbios_tables = ovmf_create_smbios_tables, > + .create_pir_tables = NULL, > +}; > + > +struct bios_config ovmf64_config = { > + .name = "OVMF-X64", > + > + .image = ovmf64, > + .image_size = sizeof(ovmf64), > + > + .bios_address = 0, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_load = ovmf_load, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + .pci_setup = ovmf_pci_setup, > + > + .acpi_build_tables = ovmf_acpi_build_tables, > + .create_mp_tables = NULL, > + .create_smbios_tables = ovmf_create_smbios_tables, > + .create_pir_tables = NULL, > +}; > + > +/* > + * Local variables: > + * mode: C > + * c-set-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin > Binary file tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32.bin > Binary file tools/firmware/ovmf/ovmf-ia32.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin > Binary file tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64.bin > Binary file tools/firmware/ovmf/ovmf-x64.bin has changed > > > > > > > # HG changeset patch > # User gbtju85@gmail.com > # > > Xen: Expose hvmloader/bios in libxl. > > Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded > can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). > > Sign-off-by: Bei Guan <gbtju85@gmail.com> > > diff -r 0f36c2eec2e1 tools/libxl/libxl.idl > --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 > @@ -137,6 +137,7 @@ > > libxl_domain_create_info = Struct("domain_create_info",[ > ("type", libxl_domain_type), > + ("hvmbios", string), > ("hap", bool), > ("oos", bool), > ("ssidref", uint32), > diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 > @@ -407,6 +407,10 @@ > if (info->poolname) > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), > info->poolname, strlen(info->poolname)); > > + if (info->hvmbios){ > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", > dom_path), info->hvmbios, strlen(info->hvmbios)); > + } > + > libxl__xs_writev(gc, t, dom_path, info->xsdata); > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), > info->platformdata); > > diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 > @@ -804,6 +804,7 @@ > char *vm_path; > char **pass_stuff; > const char *dm; > + char *custom_bios; > > if (info->device_model_stubdomain) { > libxl_device_vfb vfb; > @@ -835,10 +836,13 @@ > goto out; > } > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > - xs_mkdir(ctx->xsh, XBT_NULL, path); > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > - "%s", libxl__domain_bios(gc, info)); > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, > "/local/domain/%d/hvmloader/bios", info->domid)); > + if (!custom_bios) { > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > + xs_mkdir(ctx->xsh, XBT_NULL, path); > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > + "%s", libxl__domain_bios(gc, info)); > + } > > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", > info->domid); > xs_mkdir(ctx->xsh, XBT_NULL, path); > diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 > @@ -567,6 +567,10 @@ > } > } > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > + c_info->hvmbios = strdup(buf); > + } > + > c_info->type = LIBXL_DOMAIN_TYPE_PV; > if (!xlu_cfg_get_string (config, "builder", &buf) && > !strncmp(buf, "hvm", strlen(buf))) > > > > > Thanks, > Bei Guan > > > > > 2011/8/4 Ian Jackson <Ian.Jackson@eu.citrix.com> >> Keir Fraser writes ("Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) >> support in Xen-unstable HVM"): >>> I''d probably prefer to let xend grow obsolete quietly than add further >>> features. Noone''s maintaining it to fix it up if new features break it. No >>> strong opinion on that though, it''s up to the tools maintainers. >> >> I would agree. I would want a compelling reason (or strong community >> support) to accept new feature patches to xend. >> >> Ian. > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-05 12:16 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 05/08/2011 04:20, "Bei Guan" <gbtju85@gmail.com> wrote:> Hi All, > > Thank you for all your comments. I has removed the patch for xend and modified > some other little stuff according to your comments. > I have rebased my patches on the top of the latest Xen-unstable version > (changeset: 23756:0f36c2eec2e). > Is there any more comment? Thank you very much.Apart from the pci_setup hook I just emailed about, hopefully we can avoid code duplication in the init_vm86_tss hook as well. I''m not sure why we even need the hook -- I''ll need to check what it''s for with Ian Campbell (cc''ed). - Keir> In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is copied > form method pci_setup() in hvmloader/pci.c except for all the VGA related > stuff. This method is assigned to bios->pci_setup(). The reason for adding > such a method is stated here: > http://sourceforge.net/mailarchive/message.php?msg_id=27854247 > > > The patches are also available at > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_s > upport.patch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.pa > tch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmw > are.patch > > > # HG changeset patch > # User gbtju85@gmail.com > # > > Enable Xen-unstable hvmloader to load OVMF BIOS. > It supports OVMF BIOS in IA32 and X86 environment. > > Usage: > Add an option field in HVM config file. > # OVMF support. When enabled, hvmloader can load OVMF bios of > IA32("ovmf-ia32") and X64("ovmf-x64") > hvmbios = "ovmf-ia32" > #hvmbios = "ovmf-x64" > > Note: > Enable the HVM guest ACPI: acpi=1 > Use the OVMF to boot into a UEFI-aware OS, such as > ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', > ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > @@ -43,6 +43,19 @@ > CFLAGS += -DENABLE_ROMBIOS > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > endif > +OVMF_DIR := ../ovmf > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > + > +ifneq ($(OVMF32_ROM),) > +OBJS += ovmf.o > +endif > + > +ifneq ($(OVMF64_ROM),) > +OBJS += ovmf.o > +endif > > ifneq ($(SEABIOS_DIR),) > OBJS += seabios.o > @@ -69,7 +82,7 @@ > $(OBJCOPY) hvmloader.tmp hvmloader > rm -f hvmloader.tmp > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > ../etherboot/eb-roms.h > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) > ../etherboot/eb-roms.h > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > ifneq ($(ROMBIOS_ROM),) > @@ -84,6 +97,30 @@ > echo "#endif" >> $@.new > endif > > +ifneq ($(OVMF32_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > ifneq ($(STDVGA_ROM),) > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > @@ -3,7 +3,7 @@ > > #include <stdint.h> > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > extern enum virtual_vga virtual_vga; > > struct bios_config { > @@ -27,6 +27,7 @@ > > void (*vm86_setup)(void); > void (*e820_setup)(void); > + void (*pci_setup)(void); > > void (*acpi_build_tables)(void); > void (*create_mp_tables)(void); > @@ -36,6 +37,8 @@ > > extern struct bios_config rombios_config; > extern struct bios_config seabios_config; > +extern struct bios_config ovmf32_config; > +extern struct bios_config ovmf64_config; > > #define PAGE_SHIFT 12 > #define PAGE_SIZE (1ul << PAGE_SHIFT) > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 > @@ -361,6 +361,8 @@ > #ifdef ENABLE_SEABIOS > { "seabios", &seabios_config, }, > #endif > + { "ovmf-ia32", &ovmf32_config, }, > + { "ovmf-x64", &ovmf64_config, }, > { NULL, NULL } > }; > > @@ -420,7 +422,11 @@ > printf("CPU speed is %u MHz\n", get_cpu_mhz()); > > apic_setup(); > - pci_setup(); > + if (bios->pci_setup) { > + bios->pci_setup(); > + } else { > + pci_setup(); > + } > > smp_initialise(); > > @@ -471,6 +477,8 @@ > vgabios_sz = round_option_rom( > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > break; > + case VGA_custom: > + break; > default: > printf("No emulated VGA adaptor ...\n"); > break; > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800 > @@ -0,0 +1,394 @@ > +/* > + * HVM OVMF UEFI support. > + * > + * Bei Guan, gbtju85@gmail.com > + * Andrei Warkentin, andreiw@motorola.com > + * Leendert van Doorn, leendert@watson.ibm.com > + * Copyright (c) 2005, International Business Machines Corporation. > + * Copyright (c) 2006, Keir Fraser, XenSource Inc. > + * Copyright (c) 2011, Citrix Inc. > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms and conditions of the GNU General Public License, > + * version 2, as published by the Free Software Foundation. > + * > + * This program is distributed in the hope it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > with > + * this program; if not, write to the Free Software Foundation, Inc., 59 > Temple > + * Place - Suite 330, Boston, MA 02111-1307 USA. > + */ > + > +#include "config.h" > +#include "smbios_types.h" > +#include "acpi/acpi2_0.h" > +#include "apic_regs.h" > +#include "../rombios/config.h" > +#include "util.h" > +#include "pci_regs.h" > +#include "hypercall.h" > + > +#include <xen/hvm/params.h> > +#include <xen/hvm/ioreq.h> > +#include <xen/memory.h> > + > +#define ROM_INCLUDE_OVMF32 > +#define ROM_INCLUDE_OVMF64 > +#define ROM_INCLUDE_OVMF32_CIRRUS_VGA > +#define ROM_INCLUDE_OVMF64_CIRRUS_VGA > +#include "roms.inc" > + > +#define OVMF_BEGIN 0xFFF00000ULL > +#define OVMF_SIZE 0x00100000ULL > +#define OVMF_MAXOFFSET 0x000FFFFFULL > +#define OVMF_END (OVMF_BEGIN + OVMF_SIZE) > +#define LOWCHUNK_BEGIN 0x000F0000 > +#define LOWCHUNK_SIZE 0x00010000 > +#define LOWCHUNK_MAXOFFSET 0x0000FFFF > +#define LOWCHUNK_END (OVMF_BEGIN + OVMF_SIZE) > + > +/* > + * Set up an empty TSS area for virtual 8086 mode to use. > + * The only important thing is that it musn''t have any bits set > + * in the interrupt redirection bitmap, so all zeros will do. > + */ > +static void ovmf_init_vm86_tss(void) > +{ > + void *tss; > + struct xen_hvm_param p; > + > + tss = mem_alloc(128, 128); > + memset(tss, 0, 128); > + p.domid = DOMID_SELF; > + p.index = HVM_PARAM_VM86_TSS; > + p.value = virt_to_phys(tss); > + hypercall_hvm_op(HVMOP_set_param, &p); > + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > +} > + > +static void ovmf_load(const struct bios_config *config) > +{ > + xen_pfn_t mfn; > + uint64_t addr = OVMF_BEGIN; > + > + virtual_vga = VGA_custom; > + > + /* Copy video ROM. */ > + if (config == &ovmf32_config) { > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > + ovmf32_cirrus_vga, sizeof(ovmf32_cirrus_vga)); > + printf("OVMF32 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf32_cirrus_vga)); > + } else if (config == &ovmf64_config) { > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > + ovmf64_cirrus_vga, sizeof(ovmf64_cirrus_vga)); > + printf("OVMF64 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf64_cirrus_vga)); > + } > + > + /* Copy low-reset vector portion. */ > + memcpy((void *) LOWCHUNK_BEGIN, (uint8_t *) config->image > + + OVMF_SIZE > + - LOWCHUNK_SIZE, > + LOWCHUNK_SIZE); > + > + /* Ensure we have backing page prior to moving FD. */ > + while ((addr >> PAGE_SHIFT) != (OVMF_END >> PAGE_SHIFT)) { > + mfn = (uint32_t) (addr >> PAGE_SHIFT); > + addr += PAGE_SIZE; > + > + mem_hole_populate_ram(mfn, 1); > + } > + > + printf("Initialized FD backing pages...\n"); > + > + /* Copy FD. */ > + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); > + printf("Load complete!\n"); > +} > + > +/* > + * Ideally this function should just adjust the low memory size so MMIO fits, > + * everything else should be done in UEFI code > + */ > +static void ovmf_pci_setup(void) > +{ > + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; > + uint16_t class, vendor_id, device_id; > + unsigned int bar, pin, link, isa_irq; > + > + /* Resources assignable to PCI devices via BARs. */ > + struct resource { > + uint32_t base, max; > + } *resource, mem_resource, io_resource; > + > + /* Create a list of device BARs in descending order of size. */ > + struct bars { > + uint32_t devfn, bar_reg, bar_sz; > + } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS; > + unsigned int i, nr_bars = 0; > + > + /* Program PCI-ISA bridge with appropriate link routes. */ > + isa_irq = 0; > + for ( link = 0; link < 4; link++ ) > + { > + do { isa_irq = (isa_irq + 1) & 15; > + } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ); > + pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); > + printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); > + } > + > + /* Program ELCR to match PCI-wired IRQs. */ > + outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0)); > + outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8)); > + > + /* Scan the PCI bus and map resources. */ > + for ( devfn = 0; devfn < 256; devfn++ ) > + { > + class = pci_readw(devfn, PCI_CLASS_DEVICE); > + vendor_id = pci_readw(devfn, PCI_VENDOR_ID); > + device_id = pci_readw(devfn, PCI_DEVICE_ID); > + if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) > + continue; > + > + ASSERT((devfn != PCI_ISA_DEVFN) || > + ((vendor_id == 0x8086) && (device_id == 0x7000))); > + > + switch ( class ) > + { > + case 0x0680: > + /* PIIX4 ACPI PM. Special device with special PCI config space. > */ > + ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); > + pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ > + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ > + pci_writew(devfn, 0x22, 0x0000); > + pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ > + pci_writew(devfn, 0x3d, 0x0001); > + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1); > + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ > + break; > + case 0x0101: > + if ( vendor_id == 0x8086 ) > + { > + /* Intel ICHs since PIIX3: enable IDE legacy mode. */ > + pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */ > + pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */ > + } > + break; > + } > + > + /* Map the I/O memory and port resources. */ > + for ( bar = 0; bar < 7; bar++ ) > + { > + bar_reg = PCI_BASE_ADDRESS_0 + 4*bar; > + if ( bar == 6 ) > + bar_reg = PCI_ROM_ADDRESS; > + > + bar_data = pci_readl(devfn, bar_reg); > + pci_writel(devfn, bar_reg, ~0); > + bar_sz = pci_readl(devfn, bar_reg); > + pci_writel(devfn, bar_reg, bar_data); > + if ( bar_sz == 0 ) > + continue; > + > + bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY) ? > + PCI_BASE_ADDRESS_MEM_MASK : > + (PCI_BASE_ADDRESS_IO_MASK & 0xffff)); > + bar_sz &= ~(bar_sz - 1); > + > + for ( i = 0; i < nr_bars; i++ ) > + if ( bars[i].bar_sz < bar_sz ) > + break; > + > + if ( i != nr_bars ) > + memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars)); > + > + bars[i].devfn = devfn; > + bars[i].bar_reg = bar_reg; > + bars[i].bar_sz = bar_sz; > + > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY ) > + mmio_total += bar_sz; > + > + nr_bars++; > + > + /* Skip the upper-half of the address for a 64-bit BAR. */ > + if ( (bar_data & (PCI_BASE_ADDRESS_SPACE | > + PCI_BASE_ADDRESS_MEM_TYPE_MASK)) => + (PCI_BASE_ADDRESS_SPACE_MEMORY | > + PCI_BASE_ADDRESS_MEM_TYPE_64) ) > + bar++; > + } > + > + /* Map the interrupt. */ > + pin = pci_readb(devfn, PCI_INTERRUPT_PIN); > + if ( pin != 0 ) > + { > + /* This is the barber''s pole mapping used by Xen. */ > + link = ((pin - 1) + (devfn >> 3)) & 3; > + isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link); > + pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq); > + printf("pci dev %02x:%x INT%c->IRQ%u\n", > + devfn>>3, devfn&7, ''A''+pin-1, isa_irq); > + } > + > + /* Enable bus mastering. */ > + cmd = pci_readw(devfn, PCI_COMMAND); > + cmd |= PCI_COMMAND_MASTER; > + pci_writew(devfn, PCI_COMMAND, cmd); > + } > + > + while ( (mmio_total > (pci_mem_end - pci_mem_start)) && > + ((pci_mem_start << 1) != 0) ) > + pci_mem_start <<= 1; > + > + while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend ) > + { > + struct xen_add_to_physmap xatp; > + if ( hvm_info->high_mem_pgend == 0 ) > + hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT); > + xatp.domid = DOMID_SELF; > + xatp.space = XENMAPSPACE_gmfn; > + xatp.idx = --hvm_info->low_mem_pgend; > + xatp.gpfn = hvm_info->high_mem_pgend++; > + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > + BUG(); > + } > + > + mem_resource.base = pci_mem_start; > + mem_resource.max = pci_mem_end; > + io_resource.base = 0xc000; > + io_resource.max = 0x10000; > + > + /* Assign iomem and ioport resources in descending order of size. */ > + for ( i = 0; i < nr_bars; i++ ) > + { > + devfn = bars[i].devfn; > + bar_reg = bars[i].bar_reg; > + bar_sz = bars[i].bar_sz; > + > + bar_data = pci_readl(devfn, bar_reg); > + > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY ) > + { > + resource = &mem_resource; > + bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK; > + } > + else > + { > + resource = &io_resource; > + bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; > + } > + > + base = (resource->base + bar_sz - 1) & ~(bar_sz - 1); > + bar_data |= base; > + base += bar_sz; > + > + if ( (base < resource->base) || (base > resource->max) ) > + { > + printf("pci dev %02x:%x bar %02x size %08x: no space for " > + "resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz); > + continue; > + } > + > + resource->base = base; > + > + pci_writel(devfn, bar_reg, bar_data); > + printf("pci dev %02x:%x bar %02x size %08x: %08x\n", > + devfn>>3, devfn&7, bar_reg, bar_sz, bar_data); > + > + /* Now enable the memory or I/O mapping. */ > + cmd = pci_readw(devfn, PCI_COMMAND); > + if ( (bar_reg == PCI_ROM_ADDRESS) || > + ((bar_data & PCI_BASE_ADDRESS_SPACE) => + PCI_BASE_ADDRESS_SPACE_MEMORY) ) > + cmd |= PCI_COMMAND_MEMORY; > + else > + cmd |= PCI_COMMAND_IO; > + pci_writew(devfn, PCI_COMMAND, cmd); > + } > +} > + > +static void ovmf_acpi_build_tables(void) > +{ > + acpi_build_tables(ACPI_PHYSICAL_ADDRESS); > +} > + > +static void ovmf_create_smbios_tables(void) > +{ > + hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, > + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct > smbios_entry_point), > + SMBIOS_PHYSICAL_END); > +} > + > +struct bios_config ovmf32_config = { > + .name = "OVMF-IA32", > + > + .image = ovmf32, > + .image_size = sizeof(ovmf32), > + > + .bios_address = 0, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_load = ovmf_load, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + .pci_setup = ovmf_pci_setup, > + > + .acpi_build_tables = ovmf_acpi_build_tables, > + .create_mp_tables = NULL, > + .create_smbios_tables = ovmf_create_smbios_tables, > + .create_pir_tables = NULL, > +}; > + > +struct bios_config ovmf64_config = { > + .name = "OVMF-X64", > + > + .image = ovmf64, > + .image_size = sizeof(ovmf64), > + > + .bios_address = 0, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_load = ovmf_load, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + .pci_setup = ovmf_pci_setup, > + > + .acpi_build_tables = ovmf_acpi_build_tables, > + .create_mp_tables = NULL, > + .create_smbios_tables = ovmf_create_smbios_tables, > + .create_pir_tables = NULL, > +}; > + > +/* > + * Local variables: > + * mode: C > + * c-set-style: "BSD" > + * c-basic-offset: 4 > + * tab-width: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin > Binary file tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32.bin > Binary file tools/firmware/ovmf/ovmf-ia32.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin > Binary file tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin has changed > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64.bin > Binary file tools/firmware/ovmf/ovmf-x64.bin has changed > > > > > > > # HG changeset patch > # User gbtju85@gmail.com > # > > Xen: Expose hvmloader/bios in libxl. > > Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded > can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). > > Sign-off-by: Bei Guan <gbtju85@gmail.com> > > diff -r 0f36c2eec2e1 tools/libxl/libxl.idl > --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 > @@ -137,6 +137,7 @@ > > libxl_domain_create_info = Struct("domain_create_info",[ > ("type", libxl_domain_type), > + ("hvmbios", string), > ("hap", bool), > ("oos", bool), > ("ssidref", uint32), > diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 > @@ -407,6 +407,10 @@ > if (info->poolname) > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), > info->poolname, strlen(info->poolname)); > > + if (info->hvmbios){ > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", > dom_path), info->hvmbios, strlen(info->hvmbios)); > + } > + > libxl__xs_writev(gc, t, dom_path, info->xsdata); > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), > info->platformdata); > > diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 > @@ -804,6 +804,7 @@ > char *vm_path; > char **pass_stuff; > const char *dm; > + char *custom_bios; > > if (info->device_model_stubdomain) { > libxl_device_vfb vfb; > @@ -835,10 +836,13 @@ > goto out; > } > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > - xs_mkdir(ctx->xsh, XBT_NULL, path); > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > - "%s", libxl__domain_bios(gc, info)); > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, > "/local/domain/%d/hvmloader/bios", info->domid)); > + if (!custom_bios) { > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > + xs_mkdir(ctx->xsh, XBT_NULL, path); > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > + "%s", libxl__domain_bios(gc, info)); > + } > > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", > info->domid); > xs_mkdir(ctx->xsh, XBT_NULL, path); > diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 > @@ -567,6 +567,10 @@ > } > } > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > + c_info->hvmbios = strdup(buf); > + } > + > c_info->type = LIBXL_DOMAIN_TYPE_PV; > if (!xlu_cfg_get_string (config, "builder", &buf) && > !strncmp(buf, "hvm", strlen(buf))) > > > > > Thanks, > Bei Guan > > > > > 2011/8/4 Ian Jackson <Ian.Jackson@eu.citrix.com> >> Keir Fraser writes ("Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) >> support in Xen-unstable HVM"): >>> I''d probably prefer to let xend grow obsolete quietly than add further >>> features. Noone''s maintaining it to fix it up if new features break it. No >>> strong opinion on that though, it''s up to the tools maintainers. >> >> I would agree. I would want a compelling reason (or strong community >> support) to accept new feature patches to xend. >> >> Ian. > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Aug-09 09:58 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Fri, 2011-08-05 at 13:16 +0100, Keir Fraser wrote:> On 05/08/2011 04:20, "Bei Guan" <gbtju85@gmail.com> wrote: > > > Hi All, > > > > Thank you for all your comments. I has removed the patch for xend and modified > > some other little stuff according to your comments. > > I have rebased my patches on the top of the latest Xen-unstable version > > (changeset: 23756:0f36c2eec2e). > > Is there any more comment? Thank you very much. > > Apart from the pci_setup hook I just emailed about, hopefully we can avoid > code duplication in the init_vm86_tss hook as well. I''m not sure why we even > need the hook -- I''ll need to check what it''s for with Ian Campbell (cc''ed).I dunno ;-) I had assumed it was a rombios specific thing when I refactored for SeaBIOS (which doesn''t implement the hook). Thinking about it again is this VM86 TSS a hangover from the days where we used to "emulate" realmode using vm86 in the HVM guest context (IIRC that was called vmxassist?). Perhaps the hook can be simply dropped? Aha: changeset: 18891:6595393a3d28 user: Keir Fraser <keir.fraser@citrix.com> date: Tue Dec 09 16:28:02 2008 +0000 files: [...] description: Use virtual 8086 mode for VMX guests with CR0.PE == 0 When a VMX guest tries to enter real mode, put it in virtual 8086 mode instead, if that''s possible. Handle all errors and corner cases by falling back to the real-mode emulator. This is similar to the old VMXASSIST system except it uses Xen''s x86_emulate emulator instead of having a partial emulator in the guest firmware. It more than doubles the speed of real-mode operation on VMX. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com> Looks like it is actually needed for all BIOS types? Ian.> > - Keir > > > In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is copied > > form method pci_setup() in hvmloader/pci.c except for all the VGA related > > stuff. This method is assigned to bios->pci_setup(). The reason for adding > > such a method is stated here: > > http://sourceforge.net/mailarchive/message.php?msg_id=27854247 > > > > > > The patches are also available at > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_s > > upport.patch > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.pa > > tch > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmw > > are.patch > > > > > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > Enable Xen-unstable hvmloader to load OVMF BIOS. > > It supports OVMF BIOS in IA32 and X86 environment. > > > > Usage: > > Add an option field in HVM config file. > > # OVMF support. When enabled, hvmloader can load OVMF bios of > > IA32("ovmf-ia32") and X64("ovmf-x64") > > hvmbios = "ovmf-ia32" > > #hvmbios = "ovmf-x64" > > > > Note: > > Enable the HVM guest ACPI: acpi=1 > > Use the OVMF to boot into a UEFI-aware OS, such as > > ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', > > ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > > @@ -43,6 +43,19 @@ > > CFLAGS += -DENABLE_ROMBIOS > > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > > endif > > +OVMF_DIR := ../ovmf > > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > > + > > +ifneq ($(OVMF32_ROM),) > > +OBJS += ovmf.o > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > +OBJS += ovmf.o > > +endif > > > > ifneq ($(SEABIOS_DIR),) > > OBJS += seabios.o > > @@ -69,7 +82,7 @@ > > $(OBJCOPY) hvmloader.tmp hvmloader > > rm -f hvmloader.tmp > > > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > > ../etherboot/eb-roms.h > > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > > $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) > > ../etherboot/eb-roms.h > > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > > > ifneq ($(ROMBIOS_ROM),) > > @@ -84,6 +97,30 @@ > > echo "#endif" >> $@.new > > endif > > > > +ifneq ($(OVMF32_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > ifneq ($(STDVGA_ROM),) > > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > > @@ -3,7 +3,7 @@ > > > > #include <stdint.h> > > > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > > extern enum virtual_vga virtual_vga; > > > > struct bios_config { > > @@ -27,6 +27,7 @@ > > > > void (*vm86_setup)(void); > > void (*e820_setup)(void); > > + void (*pci_setup)(void); > > > > void (*acpi_build_tables)(void); > > void (*create_mp_tables)(void); > > @@ -36,6 +37,8 @@ > > > > extern struct bios_config rombios_config; > > extern struct bios_config seabios_config; > > +extern struct bios_config ovmf32_config; > > +extern struct bios_config ovmf64_config; > > > > #define PAGE_SHIFT 12 > > #define PAGE_SIZE (1ul << PAGE_SHIFT) > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 > > @@ -361,6 +361,8 @@ > > #ifdef ENABLE_SEABIOS > > { "seabios", &seabios_config, }, > > #endif > > + { "ovmf-ia32", &ovmf32_config, }, > > + { "ovmf-x64", &ovmf64_config, }, > > { NULL, NULL } > > }; > > > > @@ -420,7 +422,11 @@ > > printf("CPU speed is %u MHz\n", get_cpu_mhz()); > > > > apic_setup(); > > - pci_setup(); > > + if (bios->pci_setup) { > > + bios->pci_setup(); > > + } else { > > + pci_setup(); > > + } > > > > smp_initialise(); > > > > @@ -471,6 +477,8 @@ > > vgabios_sz = round_option_rom( > > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > > break; > > + case VGA_custom: > > + break; > > default: > > printf("No emulated VGA adaptor ...\n"); > > break; > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800 > > @@ -0,0 +1,394 @@ > > +/* > > + * HVM OVMF UEFI support. > > + * > > + * Bei Guan, gbtju85@gmail.com > > + * Andrei Warkentin, andreiw@motorola.com > > + * Leendert van Doorn, leendert@watson.ibm.com > > + * Copyright (c) 2005, International Business Machines Corporation. > > + * Copyright (c) 2006, Keir Fraser, XenSource Inc. > > + * Copyright (c) 2011, Citrix Inc. > > + * > > + * This program is free software; you can redistribute it and/or modify it > > + * under the terms and conditions of the GNU General Public License, > > + * version 2, as published by the Free Software Foundation. > > + * > > + * This program is distributed in the hope it will be useful, but WITHOUT > > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > > + * more details. > > + * > > + * You should have received a copy of the GNU General Public License along > > with > > + * this program; if not, write to the Free Software Foundation, Inc., 59 > > Temple > > + * Place - Suite 330, Boston, MA 02111-1307 USA. > > + */ > > + > > +#include "config.h" > > +#include "smbios_types.h" > > +#include "acpi/acpi2_0.h" > > +#include "apic_regs.h" > > +#include "../rombios/config.h" > > +#include "util.h" > > +#include "pci_regs.h" > > +#include "hypercall.h" > > + > > +#include <xen/hvm/params.h> > > +#include <xen/hvm/ioreq.h> > > +#include <xen/memory.h> > > + > > +#define ROM_INCLUDE_OVMF32 > > +#define ROM_INCLUDE_OVMF64 > > +#define ROM_INCLUDE_OVMF32_CIRRUS_VGA > > +#define ROM_INCLUDE_OVMF64_CIRRUS_VGA > > +#include "roms.inc" > > + > > +#define OVMF_BEGIN 0xFFF00000ULL > > +#define OVMF_SIZE 0x00100000ULL > > +#define OVMF_MAXOFFSET 0x000FFFFFULL > > +#define OVMF_END (OVMF_BEGIN + OVMF_SIZE) > > +#define LOWCHUNK_BEGIN 0x000F0000 > > +#define LOWCHUNK_SIZE 0x00010000 > > +#define LOWCHUNK_MAXOFFSET 0x0000FFFF > > +#define LOWCHUNK_END (OVMF_BEGIN + OVMF_SIZE) > > + > > +/* > > + * Set up an empty TSS area for virtual 8086 mode to use. > > + * The only important thing is that it musn''t have any bits set > > + * in the interrupt redirection bitmap, so all zeros will do. > > + */ > > +static void ovmf_init_vm86_tss(void) > > +{ > > + void *tss; > > + struct xen_hvm_param p; > > + > > + tss = mem_alloc(128, 128); > > + memset(tss, 0, 128); > > + p.domid = DOMID_SELF; > > + p.index = HVM_PARAM_VM86_TSS; > > + p.value = virt_to_phys(tss); > > + hypercall_hvm_op(HVMOP_set_param, &p); > > + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > > +} > > + > > +static void ovmf_load(const struct bios_config *config) > > +{ > > + xen_pfn_t mfn; > > + uint64_t addr = OVMF_BEGIN; > > + > > + virtual_vga = VGA_custom; > > + > > + /* Copy video ROM. */ > > + if (config == &ovmf32_config) { > > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > > + ovmf32_cirrus_vga, sizeof(ovmf32_cirrus_vga)); > > + printf("OVMF32 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf32_cirrus_vga)); > > + } else if (config == &ovmf64_config) { > > + memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, > > + ovmf64_cirrus_vga, sizeof(ovmf64_cirrus_vga)); > > + printf("OVMF64 Cirrus [0x%x-0x%x]\n", VGABIOS_PHYSICAL_ADDRESS, > > + VGABIOS_PHYSICAL_ADDRESS + sizeof(ovmf64_cirrus_vga)); > > + } > > + > > + /* Copy low-reset vector portion. */ > > + memcpy((void *) LOWCHUNK_BEGIN, (uint8_t *) config->image > > + + OVMF_SIZE > > + - LOWCHUNK_SIZE, > > + LOWCHUNK_SIZE); > > + > > + /* Ensure we have backing page prior to moving FD. */ > > + while ((addr >> PAGE_SHIFT) != (OVMF_END >> PAGE_SHIFT)) { > > + mfn = (uint32_t) (addr >> PAGE_SHIFT); > > + addr += PAGE_SIZE; > > + > > + mem_hole_populate_ram(mfn, 1); > > + } > > + > > + printf("Initialized FD backing pages...\n"); > > + > > + /* Copy FD. */ > > + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); > > + printf("Load complete!\n"); > > +} > > + > > +/* > > + * Ideally this function should just adjust the low memory size so MMIO fits, > > + * everything else should be done in UEFI code > > + */ > > +static void ovmf_pci_setup(void) > > +{ > > + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; > > + uint16_t class, vendor_id, device_id; > > + unsigned int bar, pin, link, isa_irq; > > + > > + /* Resources assignable to PCI devices via BARs. */ > > + struct resource { > > + uint32_t base, max; > > + } *resource, mem_resource, io_resource; > > + > > + /* Create a list of device BARs in descending order of size. */ > > + struct bars { > > + uint32_t devfn, bar_reg, bar_sz; > > + } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS; > > + unsigned int i, nr_bars = 0; > > + > > + /* Program PCI-ISA bridge with appropriate link routes. */ > > + isa_irq = 0; > > + for ( link = 0; link < 4; link++ ) > > + { > > + do { isa_irq = (isa_irq + 1) & 15; > > + } while ( !(PCI_ISA_IRQ_MASK & (1U << isa_irq)) ); > > + pci_writeb(PCI_ISA_DEVFN, 0x60 + link, isa_irq); > > + printf("PCI-ISA link %u routed to IRQ%u\n", link, isa_irq); > > + } > > + > > + /* Program ELCR to match PCI-wired IRQs. */ > > + outb(0x4d0, (uint8_t)(PCI_ISA_IRQ_MASK >> 0)); > > + outb(0x4d1, (uint8_t)(PCI_ISA_IRQ_MASK >> 8)); > > + > > + /* Scan the PCI bus and map resources. */ > > + for ( devfn = 0; devfn < 256; devfn++ ) > > + { > > + class = pci_readw(devfn, PCI_CLASS_DEVICE); > > + vendor_id = pci_readw(devfn, PCI_VENDOR_ID); > > + device_id = pci_readw(devfn, PCI_DEVICE_ID); > > + if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) > > + continue; > > + > > + ASSERT((devfn != PCI_ISA_DEVFN) || > > + ((vendor_id == 0x8086) && (device_id == 0x7000))); > > + > > + switch ( class ) > > + { > > + case 0x0680: > > + /* PIIX4 ACPI PM. Special device with special PCI config space. > > */ > > + ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); > > + pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ > > + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ > > + pci_writew(devfn, 0x22, 0x0000); > > + pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ > > + pci_writew(devfn, 0x3d, 0x0001); > > + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS_V1 | 1); > > + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ > > + break; > > + case 0x0101: > > + if ( vendor_id == 0x8086 ) > > + { > > + /* Intel ICHs since PIIX3: enable IDE legacy mode. */ > > + pci_writew(devfn, 0x40, 0x8000); /* enable IDE0 */ > > + pci_writew(devfn, 0x42, 0x8000); /* enable IDE1 */ > > + } > > + break; > > + } > > + > > + /* Map the I/O memory and port resources. */ > > + for ( bar = 0; bar < 7; bar++ ) > > + { > > + bar_reg = PCI_BASE_ADDRESS_0 + 4*bar; > > + if ( bar == 6 ) > > + bar_reg = PCI_ROM_ADDRESS; > > + > > + bar_data = pci_readl(devfn, bar_reg); > > + pci_writel(devfn, bar_reg, ~0); > > + bar_sz = pci_readl(devfn, bar_reg); > > + pci_writel(devfn, bar_reg, bar_data); > > + if ( bar_sz == 0 ) > > + continue; > > + > > + bar_sz &= (((bar_data & PCI_BASE_ADDRESS_SPACE) => > + PCI_BASE_ADDRESS_SPACE_MEMORY) ? > > + PCI_BASE_ADDRESS_MEM_MASK : > > + (PCI_BASE_ADDRESS_IO_MASK & 0xffff)); > > + bar_sz &= ~(bar_sz - 1); > > + > > + for ( i = 0; i < nr_bars; i++ ) > > + if ( bars[i].bar_sz < bar_sz ) > > + break; > > + > > + if ( i != nr_bars ) > > + memmove(&bars[i+1], &bars[i], (nr_bars-i) * sizeof(*bars)); > > + > > + bars[i].devfn = devfn; > > + bars[i].bar_reg = bar_reg; > > + bars[i].bar_sz = bar_sz; > > + > > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => > + PCI_BASE_ADDRESS_SPACE_MEMORY ) > > + mmio_total += bar_sz; > > + > > + nr_bars++; > > + > > + /* Skip the upper-half of the address for a 64-bit BAR. */ > > + if ( (bar_data & (PCI_BASE_ADDRESS_SPACE | > > + PCI_BASE_ADDRESS_MEM_TYPE_MASK)) => > + (PCI_BASE_ADDRESS_SPACE_MEMORY | > > + PCI_BASE_ADDRESS_MEM_TYPE_64) ) > > + bar++; > > + } > > + > > + /* Map the interrupt. */ > > + pin = pci_readb(devfn, PCI_INTERRUPT_PIN); > > + if ( pin != 0 ) > > + { > > + /* This is the barber''s pole mapping used by Xen. */ > > + link = ((pin - 1) + (devfn >> 3)) & 3; > > + isa_irq = pci_readb(PCI_ISA_DEVFN, 0x60 + link); > > + pci_writeb(devfn, PCI_INTERRUPT_LINE, isa_irq); > > + printf("pci dev %02x:%x INT%c->IRQ%u\n", > > + devfn>>3, devfn&7, ''A''+pin-1, isa_irq); > > + } > > + > > + /* Enable bus mastering. */ > > + cmd = pci_readw(devfn, PCI_COMMAND); > > + cmd |= PCI_COMMAND_MASTER; > > + pci_writew(devfn, PCI_COMMAND, cmd); > > + } > > + > > + while ( (mmio_total > (pci_mem_end - pci_mem_start)) && > > + ((pci_mem_start << 1) != 0) ) > > + pci_mem_start <<= 1; > > + > > + while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend ) > > + { > > + struct xen_add_to_physmap xatp; > > + if ( hvm_info->high_mem_pgend == 0 ) > > + hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT); > > + xatp.domid = DOMID_SELF; > > + xatp.space = XENMAPSPACE_gmfn; > > + xatp.idx = --hvm_info->low_mem_pgend; > > + xatp.gpfn = hvm_info->high_mem_pgend++; > > + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > > + BUG(); > > + } > > + > > + mem_resource.base = pci_mem_start; > > + mem_resource.max = pci_mem_end; > > + io_resource.base = 0xc000; > > + io_resource.max = 0x10000; > > + > > + /* Assign iomem and ioport resources in descending order of size. */ > > + for ( i = 0; i < nr_bars; i++ ) > > + { > > + devfn = bars[i].devfn; > > + bar_reg = bars[i].bar_reg; > > + bar_sz = bars[i].bar_sz; > > + > > + bar_data = pci_readl(devfn, bar_reg); > > + > > + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) => > + PCI_BASE_ADDRESS_SPACE_MEMORY ) > > + { > > + resource = &mem_resource; > > + bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK; > > + } > > + else > > + { > > + resource = &io_resource; > > + bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; > > + } > > + > > + base = (resource->base + bar_sz - 1) & ~(bar_sz - 1); > > + bar_data |= base; > > + base += bar_sz; > > + > > + if ( (base < resource->base) || (base > resource->max) ) > > + { > > + printf("pci dev %02x:%x bar %02x size %08x: no space for " > > + "resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz); > > + continue; > > + } > > + > > + resource->base = base; > > + > > + pci_writel(devfn, bar_reg, bar_data); > > + printf("pci dev %02x:%x bar %02x size %08x: %08x\n", > > + devfn>>3, devfn&7, bar_reg, bar_sz, bar_data); > > + > > + /* Now enable the memory or I/O mapping. */ > > + cmd = pci_readw(devfn, PCI_COMMAND); > > + if ( (bar_reg == PCI_ROM_ADDRESS) || > > + ((bar_data & PCI_BASE_ADDRESS_SPACE) => > + PCI_BASE_ADDRESS_SPACE_MEMORY) ) > > + cmd |= PCI_COMMAND_MEMORY; > > + else > > + cmd |= PCI_COMMAND_IO; > > + pci_writew(devfn, PCI_COMMAND, cmd); > > + } > > +} > > + > > +static void ovmf_acpi_build_tables(void) > > +{ > > + acpi_build_tables(ACPI_PHYSICAL_ADDRESS); > > +} > > + > > +static void ovmf_create_smbios_tables(void) > > +{ > > + hvm_write_smbios_tables(SMBIOS_PHYSICAL_ADDRESS, > > + SMBIOS_PHYSICAL_ADDRESS + sizeof(struct > > smbios_entry_point), > > + SMBIOS_PHYSICAL_END); > > +} > > + > > +struct bios_config ovmf32_config = { > > + .name = "OVMF-IA32", > > + > > + .image = ovmf32, > > + .image_size = sizeof(ovmf32), > > + > > + .bios_address = 0, > > + > > + .load_roms = 0, > > + > > + .optionrom_start = 0, > > + .optionrom_end = 0, > > + > > + .bios_load = ovmf_load, > > + > > + .bios_info_setup = NULL, > > + .bios_info_finish = NULL, > > + > > + .vm86_setup = ovmf_init_vm86_tss, > > + .e820_setup = NULL, > > + .pci_setup = ovmf_pci_setup, > > + > > + .acpi_build_tables = ovmf_acpi_build_tables, > > + .create_mp_tables = NULL, > > + .create_smbios_tables = ovmf_create_smbios_tables, > > + .create_pir_tables = NULL, > > +}; > > + > > +struct bios_config ovmf64_config = { > > + .name = "OVMF-X64", > > + > > + .image = ovmf64, > > + .image_size = sizeof(ovmf64), > > + > > + .bios_address = 0, > > + > > + .load_roms = 0, > > + > > + .optionrom_start = 0, > > + .optionrom_end = 0, > > + > > + .bios_load = ovmf_load, > > + > > + .bios_info_setup = NULL, > > + .bios_info_finish = NULL, > > + > > + .vm86_setup = ovmf_init_vm86_tss, > > + .e820_setup = NULL, > > + .pci_setup = ovmf_pci_setup, > > + > > + .acpi_build_tables = ovmf_acpi_build_tables, > > + .create_mp_tables = NULL, > > + .create_smbios_tables = ovmf_create_smbios_tables, > > + .create_pir_tables = NULL, > > +}; > > + > > +/* > > + * Local variables: > > + * mode: C > > + * c-set-style: "BSD" > > + * c-basic-offset: 4 > > + * tab-width: 4 > > + * indent-tabs-mode: nil > > + * End: > > + */ > > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin > > Binary file tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin has changed > > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-ia32.bin > > Binary file tools/firmware/ovmf/ovmf-ia32.bin has changed > > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin > > Binary file tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin has changed > > diff -r 0f36c2eec2e1 tools/firmware/ovmf/ovmf-x64.bin > > Binary file tools/firmware/ovmf/ovmf-x64.bin has changed > > > > > > > > > > > > > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > Xen: Expose hvmloader/bios in libxl. > > > > Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded > > can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). > > > > Sign-off-by: Bei Guan <gbtju85@gmail.com> > > > > diff -r 0f36c2eec2e1 tools/libxl/libxl.idl > > --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 > > @@ -137,6 +137,7 @@ > > > > libxl_domain_create_info = Struct("domain_create_info",[ > > ("type", libxl_domain_type), > > + ("hvmbios", string), > > ("hap", bool), > > ("oos", bool), > > ("ssidref", uint32), > > diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c > > --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -407,6 +407,10 @@ > > if (info->poolname) > > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), > > info->poolname, strlen(info->poolname)); > > > > + if (info->hvmbios){ > > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", > > dom_path), info->hvmbios, strlen(info->hvmbios)); > > + } > > + > > libxl__xs_writev(gc, t, dom_path, info->xsdata); > > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), > > info->platformdata); > > > > diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c > > --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -804,6 +804,7 @@ > > char *vm_path; > > char **pass_stuff; > > const char *dm; > > + char *custom_bios; > > > > if (info->device_model_stubdomain) { > > libxl_device_vfb vfb; > > @@ -835,10 +836,13 @@ > > goto out; > > } > > > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > > - xs_mkdir(ctx->xsh, XBT_NULL, path); > > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > > - "%s", libxl__domain_bios(gc, info)); > > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, > > "/local/domain/%d/hvmloader/bios", info->domid)); > > + if (!custom_bios) { > > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > > + xs_mkdir(ctx->xsh, XBT_NULL, path); > > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > > + "%s", libxl__domain_bios(gc, info)); > > + } > > > > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", > > info->domid); > > xs_mkdir(ctx->xsh, XBT_NULL, path); > > diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c > > --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -567,6 +567,10 @@ > > } > > } > > > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > > + c_info->hvmbios = strdup(buf); > > + } > > + > > c_info->type = LIBXL_DOMAIN_TYPE_PV; > > if (!xlu_cfg_get_string (config, "builder", &buf) && > > !strncmp(buf, "hvm", strlen(buf))) > > > > > > > > > > Thanks, > > Bei Guan > > > > > > > > > > 2011/8/4 Ian Jackson <Ian.Jackson@eu.citrix.com> > >> Keir Fraser writes ("Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) > >> support in Xen-unstable HVM"): > >>> I''d probably prefer to let xend grow obsolete quietly than add further > >>> features. Noone''s maintaining it to fix it up if new features break it. No > >>> strong opinion on that though, it''s up to the tools maintainers. > >> > >> I would agree. I would want a compelling reason (or strong community > >> support) to accept new feature patches to xend. > >> > >> Ian. > > > > > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 10:03 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 10:58, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote:>> Apart from the pci_setup hook I just emailed about, hopefully we can avoid >> code duplication in the init_vm86_tss hook as well. I''m not sure why we even >> need the hook -- I''ll need to check what it''s for with Ian Campbell (cc''ed). > > I dunno ;-) I had assumed it was a rombios specific thing when I > refactored for SeaBIOS (which doesn''t implement the hook). > > Thinking about it again is this VM86 TSS a hangover from the days where > we used to "emulate" realmode using vm86 in the HVM guest context (IIRC > that was called vmxassist?). Perhaps the hook can be simply dropped?No, as you correctly surmised it is for Tim''s realmode-emulation-acceleration. It is applicable to all guests regardless of BIOS. Shall I move it back out into common code in hvmloader.c, then? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Aug-09 10:24 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Fri, 2011-08-05 at 12:20 +0100, Bei Guan wrote:> Hi All, > > Thank you for all your comments. I has removed the patch for xend and > modified some other little stuff according to your comments. > I have rebased my patches on the top of the latest Xen-unstable > version (changeset: 23756:0f36c2eec2e). > Is there any more comment? Thank you very much. > > In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is > copied form method pci_setup() in hvmloader/pci.c except for all the > VGA related stuff. This method is assigned to bios->pci_setup(). The > reason for adding such a method is stated here: > http://sourceforge.net/mailarchive/message.php?msg_id=27854247 > > > The patches are also available at > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_support.patch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.patch > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmware.patchIn the future please can you post as 3 individual emails in a series ("hg email" or "git send-email" can help with this) instead of concatenating in a single email.> > # HG changeset patch > # User gbtju85@gmail.com > # > > Enable Xen-unstable hvmloader to load OVMF BIOS. > It supports OVMF BIOS in IA32 and X86 environment. > > Usage: > Add an option field in HVM config file. > # OVMF support. When enabled, hvmloader can load OVMF bios of IA32("ovmf-ia32") and X64("ovmf-x64") > hvmbios = "ovmf-ia32" > #hvmbios = "ovmf-x64" > > Note: > Enable the HVM guest ACPI: acpi=1 > Use the OVMF to boot into a UEFI-aware OS, such as ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > @@ -43,6 +43,19 @@ > CFLAGS += -DENABLE_ROMBIOS > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > endif > +OVMF_DIR := ../ovmf > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > + > +ifneq ($(OVMF32_ROM),) > +OBJS += ovmf.o > +endif > + > +ifneq ($(OVMF64_ROM),) > +OBJS += ovmf.o > +endif > > ifneq ($(SEABIOS_DIR),) > OBJS += seabios.o > @@ -69,7 +82,7 @@ > $(OBJCOPY) hvmloader.tmp hvmloader > rm -f hvmloader.tmp > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) ../etherboot/eb-roms.h > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) ../etherboot/eb-roms.h > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > ifneq ($(ROMBIOS_ROM),) > @@ -84,6 +97,30 @@ > echo "#endif" >> $@.new > endif > > +ifneq ($(OVMF32_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endif > + > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > + echo "#endif" >> $@.new > +endifWhat is the difference between these versions of the VGA BIOS and the existing one? It seems like you only checking the binaries, where is the source and what is its license? With SeaBIOS we moved to a model of loading option ROMs from the emulated devices themselves (via the ROM BAR). Could this be used for OVMF too? Currently QEMU hardcodes the host path to the ROM Image for various devices but I think it would be a valid improvement to qemu to allow this to be specified on the qemu command line. It''s not clear if the Xen source tree, the QEMU source tree or the OVMF source would then be the right home for the VGABIOS images in that case.> + > ifneq ($(STDVGA_ROM),) > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > @@ -3,7 +3,7 @@ > > #include <stdint.h> > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > extern enum virtual_vga virtual_vga; > > struct bios_config { > @@ -27,6 +27,7 @@ > > void (*vm86_setup)(void); > void (*e820_setup)(void); > + void (*pci_setup)(void); > > void (*acpi_build_tables)(void); > void (*create_mp_tables)(void); > @@ -36,6 +37,8 @@ > > extern struct bios_config rombios_config; > extern struct bios_config seabios_config; > +extern struct bios_config ovmf32_config; > +extern struct bios_config ovmf64_config; > > #define PAGE_SHIFT 12 > #define PAGE_SIZE (1ul << PAGE_SHIFT) > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 > @@ -361,6 +361,8 @@ > #ifdef ENABLE_SEABIOS > { "seabios", &seabios_config, }, > #endif > + { "ovmf-ia32", &ovmf32_config, }, > + { "ovmf-x64", &ovmf64_config, },I suppose these (asymmetric) names are OVMF-isms?> { NULL, NULL } > }; > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800[...]> + * Set up an empty TSS area for virtual 8086 mode to use. > + * The only important thing is that it musn''t have any bits set > + * in the interrupt redirection bitmap, so all zeros will do. > + */ > +static void ovmf_init_vm86_tss(void) > +{ > + void *tss; > + struct xen_hvm_param p; > + > + tss = mem_alloc(128, 128); > + memset(tss, 0, 128); > + p.domid = DOMID_SELF; > + p.index = HVM_PARAM_VM86_TSS; > + p.value = virt_to_phys(tss); > + hypercall_hvm_op(HVMOP_set_param, &p); > + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > +}I think this can be pulled out of here and rombios.c and made common again, it seems like it is needed for all BIOSes and is not ROMBIOS specific as I first thought. Can you write up that patch or shall I?> + > +/* > + * Ideally this function should just adjust the low memory size so MMIO fits, > + * everything else should be done in UEFI code > + */ > +static void ovmf_pci_setup(void) > +{ > [...] > +}This function looks very similar to (a slightly out of date version of) the standard pci_setup. What (if any) are the actual differences? If (as I expect) they are small then I think we would be better off adding parameters/options to the existing pci_setup function and calling with appropriate arguments for the different bioses, rather than duplicating the entire function for the sake of a few small changes.> # HG changeset patch > # User gbtju85@gmail.com > # > > Xen: Expose hvmloader/bios in libxl. > > Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded > can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). > > Sign-off-by: Bei Guan <gbtju85@gmail.com> > > diff -r 0f36c2eec2e1 tools/libxl/libxl.idl > --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 > @@ -137,6 +137,7 @@please can you add: [diff] showfunc = True to ~/.hgrc. It makes patches easier to review.> libxl_domain_create_info = Struct("domain_create_info",[ > ("type", libxl_domain_type), > + ("hvmbios", string),I think this more properly belongs in libxl_domain_build_info.u.hvm i.e. alongside (the now misnamed) "firmware".> ("hap", bool), > ("oos", bool), > ("ssidref", uint32), > diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 > @@ -407,6 +407,10 @@ > if (info->poolname) > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); > > + if (info->hvmbios){ > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", dom_path), info->hvmbios, strlen(info->hvmbios)); > + } > + > libxl__xs_writev(gc, t, dom_path, info->xsdata); > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), info->platformdata); > > diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 > @@ -804,6 +804,7 @@ > char *vm_path; > char **pass_stuff; > const char *dm; > + char *custom_bios; > > if (info->device_model_stubdomain) { > libxl_device_vfb vfb; > @@ -835,10 +836,13 @@ > goto out; > } > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > - xs_mkdir(ctx->xsh, XBT_NULL, path); > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > - "%s", libxl__domain_bios(gc, info)); > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/hvmloader/bios", info->domid)); > + if (!custom_bios) { > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", info->domid); > + xs_mkdir(ctx->xsh, XBT_NULL, path); > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > + "%s", libxl__domain_bios(gc, info)); > + }This logic should be in libxl__domain_bios. I also think you should plumb the data structure containing the bios option through to this point instead of stashing it in xenstore earlier and reading it back here.> > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", info->domid); > xs_mkdir(ctx->xsh, XBT_NULL, path); > diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c > --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 > +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 > @@ -567,6 +567,10 @@ > } > } > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > + c_info->hvmbios = strdup(buf); > + }You can use xlu_cfg_replace_string here I think. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 10:34 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 11:24, "Ian Campbell" <Ian.Campbell@citrix.com> wrote:>> +static void ovmf_init_vm86_tss(void) >> +{ >> + void *tss; >> + struct xen_hvm_param p; >> + >> + tss = mem_alloc(128, 128); >> + memset(tss, 0, 128); >> + p.domid = DOMID_SELF; >> + p.index = HVM_PARAM_VM86_TSS; >> + p.value = virt_to_phys(tss); >> + hypercall_hvm_op(HVMOP_set_param, &p); >> + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); >> +} > > I think this can be pulled out of here and rombios.c and made common > again, it seems like it is needed for all BIOSes and is not ROMBIOS > specific as I first thought. Can you write up that patch or shall I?I''ve done it. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Aug-09 11:13 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, 2011-08-09 at 11:34 +0100, Keir Fraser wrote:> On 09/08/2011 11:24, "Ian Campbell" <Ian.Campbell@citrix.com> wrote: > > >> +static void ovmf_init_vm86_tss(void) > >> +{ > >> + void *tss; > >> + struct xen_hvm_param p; > >> + > >> + tss = mem_alloc(128, 128); > >> + memset(tss, 0, 128); > >> + p.domid = DOMID_SELF; > >> + p.index = HVM_PARAM_VM86_TSS; > >> + p.value = virt_to_phys(tss); > >> + hypercall_hvm_op(HVMOP_set_param, &p); > >> + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > >> +} > > > > I think this can be pulled out of here and rombios.c and made common > > again, it seems like it is needed for all BIOSes and is not ROMBIOS > > specific as I first thought. Can you write up that patch or shall I? > > I''ve done it.Ta!> > -- Keir > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Bei Guan
2011-Aug-09 12:56 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Hi, Thank you for all your comments. I will reply inline. 2011/8/9 Ian Campbell <Ian.Campbell@citrix.com>> On Fri, 2011-08-05 at 12:20 +0100, Bei Guan wrote: > > Hi All, > > > > Thank you for all your comments. I has removed the patch for xend and > > modified some other little stuff according to your comments. > > I have rebased my patches on the top of the latest Xen-unstable > > version (changeset: 23756:0f36c2eec2e). > > Is there any more comment? Thank you very much. > > > > In the patch for ovmf.c, we add a method ovmf_pci_setup(), which is > > copied form method pci_setup() in hvmloader/pci.c except for all the > > VGA related stuff. This method is assigned to bios->pci_setup(). The > > reason for adding such a method is stated here: > > http://sourceforge.net/mailarchive/message.php?msg_id=27854247 > > > > > > The patches are also available at > > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xen_support.patch > > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_xl.patch > > > https://github.com/GavinGuan/gavinguan/blob/master/xen/ovmf-support/ovmf_firmware.patch > > In the future please can you post as 3 individual emails in a series > ("hg email" or "git send-email" can help with this) instead of > concatenating in a single email. >Yes, I will post them separately in the next version patch.> > > > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > Enable Xen-unstable hvmloader to load OVMF BIOS. > > It supports OVMF BIOS in IA32 and X86 environment. > > > > Usage: > > Add an option field in HVM config file. > > # OVMF support. When enabled, hvmloader can load OVMF bios of > IA32("ovmf-ia32") and X64("ovmf-x64") > > hvmbios = "ovmf-ia32" > > #hvmbios = "ovmf-x64" > > > > Note: > > Enable the HVM guest ACPI: acpi=1 > > Use the OVMF to boot into a UEFI-aware OS, such as > ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', > ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > > @@ -43,6 +43,19 @@ > > CFLAGS += -DENABLE_ROMBIOS > > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > > endif > > +OVMF_DIR := ../ovmf > > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > > + > > +ifneq ($(OVMF32_ROM),) > > +OBJS += ovmf.o > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > +OBJS += ovmf.o > > +endif > > > > ifneq ($(SEABIOS_DIR),) > > OBJS += seabios.o > > @@ -69,7 +82,7 @@ > > $(OBJCOPY) hvmloader.tmp hvmloader > > rm -f hvmloader.tmp > > > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > ../etherboot/eb-roms.h > > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) > $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) > $(OVMF64_CIRRUS_VGA_ROM) ../etherboot/eb-roms.h > > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > > > ifneq ($(ROMBIOS_ROM),) > > @@ -84,6 +97,30 @@ > > echo "#endif" >> $@.new > > endif > > > > +ifneq ($(OVMF32_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > What is the difference between these versions of the VGA BIOS and the > existing one? >I am unsure what is the difference between OVMF VGA BIOS and the existing one in firmware/vgabios. Maybe Andrei or Jordan can give the answer.> > It seems like you only checking the binaries, where is the source and what > is its license? >The source code of OVMF BIOS is available at https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/OvmfPkg/ . And the license is BSD license. Building the OVMF BIOS needs the environment edk2, whose source code is available at https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/<https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/OvmfPkg/> . I am afraid OVMF source code can''t be downloaded and built in Xen compiling environment. So, I just provide the binary files of OVMF VGA and OVMF BIOS firmware.> > With SeaBIOS we moved to a model of loading option ROMs from the > emulated devices themselves (via the ROM BAR). Could this be used for > OVMF too?Do you mean use the bios->load_roms to load OVMF VGA BIOS instead of loading it in bios_load?> Currently QEMU hardcodes the host path to the ROM Image for > various devices but I think it would be a valid improvement to qemu to > allow this to be specified on the qemu command line. It''s not clear if > the Xen source tree, the QEMU source tree or the OVMF source would then > be the right home for the VGABIOS images in that case. > > > + > > ifneq ($(STDVGA_ROM),) > > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > > @@ -3,7 +3,7 @@ > > > > #include <stdint.h> > > > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > > extern enum virtual_vga virtual_vga; > > > > struct bios_config { > > @@ -27,6 +27,7 @@ > > > > void (*vm86_setup)(void); > > void (*e820_setup)(void); > > + void (*pci_setup)(void); > > > > void (*acpi_build_tables)(void); > > void (*create_mp_tables)(void); > > @@ -36,6 +37,8 @@ > > > > extern struct bios_config rombios_config; > > extern struct bios_config seabios_config; > > +extern struct bios_config ovmf32_config; > > +extern struct bios_config ovmf64_config; > > > > #define PAGE_SHIFT 12 > > #define PAGE_SIZE (1ul << PAGE_SHIFT) > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 > +0100 > > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 > +0800 > > @@ -361,6 +361,8 @@ > > #ifdef ENABLE_SEABIOS > > { "seabios", &seabios_config, }, > > #endif > > + { "ovmf-ia32", &ovmf32_config, }, > > + { "ovmf-x64", &ovmf64_config, }, > > I suppose these (asymmetric) names are OVMF-isms? >Yes, these two are the names of OVMF BIOS in platform IA32 and X64.> > > { NULL, NULL } > > }; > > > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/ovmf.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/tools/firmware/hvmloader/ovmf.c Fri Aug 05 17:58:27 2011 +0800 > [...] > > + * Set up an empty TSS area for virtual 8086 mode to use. > > + * The only important thing is that it musn''t have any bits set > > + * in the interrupt redirection bitmap, so all zeros will do. > > + */ > > +static void ovmf_init_vm86_tss(void) > > +{ > > + void *tss; > > + struct xen_hvm_param p; > > + > > + tss = mem_alloc(128, 128); > > + memset(tss, 0, 128); > > + p.domid = DOMID_SELF; > > + p.index = HVM_PARAM_VM86_TSS; > > + p.value = virt_to_phys(tss); > > + hypercall_hvm_op(HVMOP_set_param, &p); > > + printf("vm86 TSS at %08lx\n", virt_to_phys(tss)); > > +} > > I think this can be pulled out of here and rombios.c and made common > again, it seems like it is needed for all BIOSes and is not ROMBIOS > specific as I first thought. Can you write up that patch or shall I? >Thanks for Keir, I will rebase my patches on the latest xen-unstable.> > + > > +/* > > + * Ideally this function should just adjust the low memory size so MMIO > fits, > > + * everything else should be done in UEFI code > > + */ > > +static void ovmf_pci_setup(void) > > +{ > > [...] > > +} > > This function looks very similar to (a slightly out of date version of) > the standard pci_setup. What (if any) are the actual differences? >The difference is that in ovmf_pci_setup(), we remove the code related to VGA setup, because we need to use the OVMF VGA bios. However, after Keir''s comments, we have some testing and find that pci_setup() also works well for loading OVMF BIOS. So, we will remove the ovmf_pci_setup() and use the existing pci_setup() function.> > If (as I expect) they are small then I think we would be better off > adding parameters/options to the existing pci_setup function and calling > with appropriate arguments for the different bioses, rather than > duplicating the entire function for the sake of a few small changes.> > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > Xen: Expose hvmloader/bios in libxl. > > > > Exposes the hvmloader/bios xenstore key in libxl, so firmware loaded > > can be overriden (choices: rombios, seabios, ovmf-ia32, ovmf-x64). > > > > Sign-off-by: Bei Guan <gbtju85@gmail.com> > > > > diff -r 0f36c2eec2e1 tools/libxl/libxl.idl > > --- a/tools/libxl/libxl.idl Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl.idl Fri Aug 05 18:13:37 2011 +0800 > > @@ -137,6 +137,7 @@ > > please can you add: > [diff] > showfunc = True > to ~/.hgrc. It makes patches easier to review. > > > libxl_domain_create_info = Struct("domain_create_info",[ > > ("type", libxl_domain_type), > > + ("hvmbios", string), > > I think this more properly belongs in libxl_domain_build_info.u.hvm i.e. > alongside (the now misnamed) "firmware". > > > ("hap", bool), > > ("oos", bool), > > ("ssidref", uint32), > > diff -r 0f36c2eec2e1 tools/libxl/libxl_create.c > > --- a/tools/libxl/libxl_create.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl_create.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -407,6 +407,10 @@ > > if (info->poolname) > > xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/pool_name", > vm_path), info->poolname, strlen(info->poolname)); > > > > + if (info->hvmbios){ > > + xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/hvmloader/bios", > dom_path), info->hvmbios, strlen(info->hvmbios)); > > + } > > + > > libxl__xs_writev(gc, t, dom_path, info->xsdata); > > libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), > info->platformdata); > > > > diff -r 0f36c2eec2e1 tools/libxl/libxl_dm.c > > --- a/tools/libxl/libxl_dm.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/libxl_dm.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -804,6 +804,7 @@ > > char *vm_path; > > char **pass_stuff; > > const char *dm; > > + char *custom_bios; > > > > if (info->device_model_stubdomain) { > > libxl_device_vfb vfb; > > @@ -835,10 +836,13 @@ > > goto out; > > } > > > > - path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", > info->domid); > > - xs_mkdir(ctx->xsh, XBT_NULL, path); > > - libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", path), > > - "%s", libxl__domain_bios(gc, info)); > > + custom_bios = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, > "/local/domain/%d/hvmloader/bios", info->domid)); > > + if (!custom_bios) { > > + path = libxl__sprintf(gc, "/local/domain/%d/hvmloader", > info->domid); > > + xs_mkdir(ctx->xsh, XBT_NULL, path); > > + libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/bios", > path), > > + "%s", libxl__domain_bios(gc, info)); > > + } > > This logic should be in libxl__domain_bios. I also think you should > plumb the data structure containing the bios option through to this > point instead of stashing it in xenstore earlier and reading it back > here. > > > > > path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", > info->domid); > > xs_mkdir(ctx->xsh, XBT_NULL, path); > > diff -r 0f36c2eec2e1 tools/libxl/xl_cmdimpl.c > > --- a/tools/libxl/xl_cmdimpl.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/libxl/xl_cmdimpl.c Fri Aug 05 18:13:37 2011 +0800 > > @@ -567,6 +567,10 @@ > > } > > } > > > > + if (!xlu_cfg_get_string (config, "hvmbios", &buf)){ > > + c_info->hvmbios = strdup(buf); > > + } > > You can use xlu_cfg_replace_string here I think. >Thank you for the comments for OVMF supporting in libxl. I will modify it. Best Regards, Bei Guan> > Ian. > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Aug-09 14:39 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, 2011-08-09 at 13:56 +0100, Bei Guan wrote:> > > > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > Enable Xen-unstable hvmloader to load OVMF BIOS. > > It supports OVMF BIOS in IA32 and X86 environment. > > > > Usage: > > Add an option field in HVM config file. > > # OVMF support. When enabled, hvmloader can load OVMF bios of IA32("ovmf-ia32") and X64("ovmf-x64") > > hvmbios = "ovmf-ia32" > > #hvmbios = "ovmf-x64" > > > > Note: > > Enable the HVM guest ACPI: acpi=1 > > Use the OVMF to boot into a UEFI-aware OS, such as ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this: > > disk = [ ''file:/root/<img_name>.img,ioemu:hda,w'', ''file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r'' ] > > > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/Makefile > > --- a/tools/firmware/hvmloader/Makefile Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/Makefile Fri Aug 05 17:58:27 2011 +0800 > > @@ -43,6 +43,19 @@ > > CFLAGS += -DENABLE_ROMBIOS > > ROMBIOS_ROM := $(ROMBIOS_DIR)/BIOS-bochs-latest > > endif > > +OVMF_DIR := ../ovmf > > +OVMF32_ROM := $(OVMF_DIR)/ovmf-ia32.bin > > +OVMF64_ROM := $(OVMF_DIR)/ovmf-x64.bin > > +OVMF32_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-ia32-cirrus-vga.bin > > +OVMF64_CIRRUS_VGA_ROM := $(OVMF_DIR)/ovmf-x64-cirrus-vga.bin > > + > > +ifneq ($(OVMF32_ROM),) > > +OBJS += ovmf.o > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > +OBJS += ovmf.o > > +endif > > > > ifneq ($(SEABIOS_DIR),) > > OBJS += seabios.o > > @@ -69,7 +82,7 @@ > > $(OBJCOPY) hvmloader.tmp hvmloader > > rm -f hvmloader.tmp > > > > -roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) ../etherboot/eb-roms.h > > +roms.inc: $(ROMBIOS_ROM) $(SEABIOS_ROM) $(STDVGA_ROM) $(CIRRUSVGA_ROM) $(OVMF32_ROM) $(OVMF64_ROM) $(OVMF32_CIRRUS_VGA_ROM) $(OVMF64_CIRRUS_VGA_ROM) ../etherboot/eb-roms.h > > echo "/* Autogenerated file. DO NOT EDIT */" > $@.new > > > > ifneq ($(ROMBIOS_ROM),) > > @@ -84,6 +97,30 @@ > > echo "#endif" >> $@.new > > endif > > > > +ifneq ($(OVMF32_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32" >> $@.new > > + sh ./mkhex ovmf32 $(OVMF32_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64" >> $@.new > > + sh ./mkhex ovmf64 $(OVMF64_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF32_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF32_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf32_cirrus_vga $(OVMF32_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > + > > +ifneq ($(OVMF64_CIRRUS_VGA_ROM),) > > + echo "#ifdef ROM_INCLUDE_OVMF64_CIRRUS_VGA" >> $@.new > > + sh ./mkhex ovmf64_cirrus_vga $(OVMF64_CIRRUS_VGA_ROM) >> $@.new > > + echo "#endif" >> $@.new > > +endif > > > What is the difference between these versions of the VGA BIOS and the existing one? > I am unsure what is the difference between OVMF VGA BIOS and the existing one in firmware/vgabios. Maybe Andrei or Jordan can give the answer.Yes please.> > > > > It seems like you only checking the binaries, where is the source and what is its license? > The source code of OVMF BIOS is available at > https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/OvmfPkg/ . > And the license is BSD license. > > > Building the OVMF BIOS needs the environment edk2, whose source code is available at > https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/ . > I am afraid OVMF source code can''t be downloaded and built in Xen compiling environment. > So, I just provide the binary files of OVMF VGA and OVMF BIOS firmware.Oh, I see. Generally we would like to avoid adding new external projects to the Xen source tree. Long term we would instead like to see a kind of "meta" build system which pulls together Xen and the various bits and pieces. In the seabios case we decided not to pull any bits seabios into xen.hg/tools/firmware/seabios/ but rather to provide a configuration variable which would point to a built seabios.git tree. I think a similar model would make sense for the OVMF support. IOW OVMF_DIR = "" by default (OVMF disabled), users who want OVMF can obtain and build OVMF and then set OVMF_DIR to point this built tree. (eventually this step will be subsumed into the "meta" build system)> > > > > With SeaBIOS we moved to a model of loading option ROMs from the > emulated devices themselves (via the ROM BAR). Could this be used for > OVMF too? > Do you mean use the bios->load_roms to load OVMF VGA BIOS instead of loading it in bios_load?No. Hardware devices have a special BAR which can be used to map their option ROM. BIOSes (i.e. real ones on physical machines) use this in order to map the option ROMs and copy or run them etc. SeaBIOS also supports this and qemu supports emulating these BARs for the given devices by providing the contents of a specific file on the host file system and so we don''t load any VGA BIOS in hvmloader in that case and just let seabios and qemu take care of it via this mechanism. So what I''m suggesting is that OVMF should (and possibly already does) support this operation and should load the VGA rom itself from the VGA devices ROM BAR. If the VGABIOS for OVMF needs to be different to what would be normally need with a legacy BIOS then we can enhance QEMU to provide the option to request alternative ROM images be used. This model makes sense since a device''s option-ROM is tied more to the specific device than it is to the BIOS etc.> > > > + > > ifneq ($(STDVGA_ROM),) > > echo "#ifdef ROM_INCLUDE_VGABIOS" >> $@.new > > sh ./mkhex vgabios_stdvga $(STDVGA_ROM) >> $@.new > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/config.h > > --- a/tools/firmware/hvmloader/config.h Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/config.h Fri Aug 05 17:58:27 2011 +0800 > > @@ -3,7 +3,7 @@ > > > > #include <stdint.h> > > > > -enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt }; > > +enum virtual_vga { VGA_none, VGA_std, VGA_cirrus, VGA_pt, VGA_custom }; > > extern enum virtual_vga virtual_vga; > > > > struct bios_config { > > @@ -27,6 +27,7 @@ > > > > void (*vm86_setup)(void); > > void (*e820_setup)(void); > > + void (*pci_setup)(void); > > > > void (*acpi_build_tables)(void); > > void (*create_mp_tables)(void); > > @@ -36,6 +37,8 @@ > > > > extern struct bios_config rombios_config; > > extern struct bios_config seabios_config; > > +extern struct bios_config ovmf32_config; > > +extern struct bios_config ovmf64_config; > > > > #define PAGE_SHIFT 12 > > #define PAGE_SIZE (1ul << PAGE_SHIFT) > > diff -r 0f36c2eec2e1 tools/firmware/hvmloader/hvmloader.c > > --- a/tools/firmware/hvmloader/hvmloader.c Thu Jul 28 15:40:54 2011 +0100 > > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 05 17:58:27 2011 +0800 > > @@ -361,6 +361,8 @@ > > #ifdef ENABLE_SEABIOS > > { "seabios", &seabios_config, }, > > #endif > > + { "ovmf-ia32", &ovmf32_config, }, > > + { "ovmf-x64", &ovmf64_config, }, > > > I suppose these (asymmetric) names are OVMF-isms? > Yes, these two are the names of OVMF BIOS in platform IA32 and X64.Ick, but oh well... Is there any reason to prefer one to the other? How do I choose which one I want? Can it be autodetected?> > + > > +/* > > + * Ideally this function should just adjust the low memory size so MMIO fits, > > + * everything else should be done in UEFI code > > + */ > > +static void ovmf_pci_setup(void) > > +{ > > > [...] > > +} > > This function looks very similar to (a slightly out of date version of) > the standard pci_setup. What (if any) are the actual differences?> The difference is that in ovmf_pci_setup(), we remove the code related to VGA setup, because we need to use the OVMF VGA bios. > However, after Keir''s comments, we have some testing and find that pci_setup() also works well for loading OVMF BIOS. > So, we will remove the ovmf_pci_setup() and use the existing pci_setup() function.Great. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 14:47 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 15:39, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote:>>> + { "ovmf-ia32", &ovmf32_config, }, >>> + { "ovmf-x64", &ovmf64_config, }, >> >> >> I suppose these (asymmetric) names are OVMF-isms? >> Yes, these two are the names of OVMF BIOS in platform IA32 and X64. > > Ick, but oh well... > > Is there any reason to prefer one to the other? How do I choose which > one I want? Can it be autodetected?I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support one config option -- "ovmf" -- and have hvmloader auto-load the appropriate OVMF build, based on CPUID.long_mode. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Aug-09 14:56 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, 2011-08-09 at 15:47 +0100, Keir Fraser wrote:> On 09/08/2011 15:39, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote: > > >>> + { "ovmf-ia32", &ovmf32_config, }, > >>> + { "ovmf-x64", &ovmf64_config, }, > >> > >> > >> I suppose these (asymmetric) names are OVMF-isms? > >> Yes, these two are the names of OVMF BIOS in platform IA32 and X64. > > > > Ick, but oh well... > > > > Is there any reason to prefer one to the other? How do I choose which > > one I want? Can it be autodetected? > > I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., > ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support > one config option -- "ovmf" -- and have hvmloader auto-load the appropriate > OVMF build, based on CPUID.long_mode.Yes, that''s the sort of thing I was getting at. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jordan Justen
2011-Aug-09 20:19 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, Aug 9, 2011 at 07:56, Ian Campbell <Ian.Campbell@eu.citrix.com> wrote:> On Tue, 2011-08-09 at 15:47 +0100, Keir Fraser wrote: >> On 09/08/2011 15:39, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote: >> >> >>> + { "ovmf-ia32", &ovmf32_config, }, >> >>> + { "ovmf-x64", &ovmf64_config, }, >> >> >> >> >> >> I suppose these (asymmetric) names are OVMF-isms? >> >> Yes, these two are the names of OVMF BIOS in platform IA32 and X64. >> > >> > Ick, but oh well... >> > >> > Is there any reason to prefer one to the other? How do I choose which >> > one I want? Can it be autodetected? >> >> I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., >> ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support >> one config option -- "ovmf" -- and have hvmloader auto-load the appropriate >> OVMF build, based on CPUID.long_mode. > > Yes, that''s the sort of thing I was getting at.The IA32 firmware is used for IA32 UEFI operating systems, and the X64 firmware is used for X64 operating systems. X64 is somewhat more commonly used on modern systems. There could be an auto-detect mode for the default of IA32 or X64 based on the installed CPU, but there might still be a case where someone would prefer to run OVMF IA32 on an X64 processor. -Jordan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Andrei Warkentin
2011-Aug-09 20:25 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, Aug 9, 2011 at 9:47 AM, Keir Fraser <keir@xen.org> wrote:> On 09/08/2011 15:39, "Ian Campbell" <Ian.Campbell@eu.citrix.com> wrote: > >>>> + { "ovmf-ia32", &ovmf32_config, }, >>>> + { "ovmf-x64", &ovmf64_config, }, >>> >>> >>> I suppose these (asymmetric) names are OVMF-isms? >>> Yes, these two are the names of OVMF BIOS in platform IA32 and X64. >> >> Ick, but oh well... >> >> Is there any reason to prefer one to the other? How do I choose which >> one I want? Can it be autodetected? > > I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., > ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support > one config option -- "ovmf" -- and have hvmloader auto-load the appropriate > OVMF build, based on CPUID.long_mode. >As Jordan mentioned, 32-bit EFI can only boot 32-bit EFI applications (that might mean 32-bit bootloader for 64-bit OS). 64-bit EFI can only boot 64-bit applications. X64 is what is the "de facto" standard in the commerical PC/server world (for example - 2008, Win7 all boot UEFI way only on 64-bit), but 32-bit UEFI has been used as well and has applications in the low-power embedded x86 space. A _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 20:32 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 21:19, "Jordan Justen" <jljusten@gmail.com> wrote:>>> I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., >>> ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support >>> one config option -- "ovmf" -- and have hvmloader auto-load the appropriate >>> OVMF build, based on CPUID.long_mode. >> >> Yes, that''s the sort of thing I was getting at. > > The IA32 firmware is used for IA32 UEFI operating systems, and the X64 > firmware is used for X64 operating systems.I assume a native box would only have one UEFI firmware, and that would be X64 on an x86/64 box. You must still be able to boot IA32 operating systems on the X64 firmware, right?> X64 is somewhat more commonly used on modern systems. > > There could be an auto-detect mode for the default of IA32 or X64 > based on the installed CPU, but there might still be a case where > someone would prefer to run OVMF IA32 on an X64 processor.Such as? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jordan Justen
2011-Aug-09 20:54 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, Aug 9, 2011 at 13:32, Keir Fraser <keir.xen@gmail.com> wrote:> On 09/08/2011 21:19, "Jordan Justen" <jljusten@gmail.com> wrote: > >>>> I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., >>>> ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support >>>> one config option -- "ovmf" -- and have hvmloader auto-load the appropriate >>>> OVMF build, based on CPUID.long_mode. >>> >>> Yes, that''s the sort of thing I was getting at. >> >> The IA32 firmware is used for IA32 UEFI operating systems, and the X64 >> firmware is used for X64 operating systems. > > I assume a native box would only have one UEFI firmware, and that would be > X64 on an x86/64 box. You must still be able to boot IA32 operating systems > on the X64 firmware, right?Yes, it could technically be booted, if the OS loader was an X64 application that transitioned to IA32 before starting the OS kernel. But, the IA32 OS would then have issues if it wanted to call UEFI runtime services, which would be X64.>> X64 is somewhat more commonly used on modern systems. >> >> There could be an auto-detect mode for the default of IA32 or X64 >> based on the installed CPU, but there might still be a case where >> someone would prefer to run OVMF IA32 on an X64 processor. > > Such as?If you had an IA32 UEFI OS, it would be better to boot the IA32 OVMF for the reason mentioned above. -Jordan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 20:56 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 21:25, "Andrei Warkentin" <andreiw@motorola.com> wrote:>> I suspect ovmf-x64 is a superset of the capabilities of ovmf-ia32 (e.g., >> ability to boot UEFI-bootable 64-bit OSes?). If so, we should only support >> one config option -- "ovmf" -- and have hvmloader auto-load the appropriate >> OVMF build, based on CPUID.long_mode. >> > > As Jordan mentioned, 32-bit EFI can only boot 32-bit EFI applications > (that might mean 32-bit bootloader for 64-bit OS). 64-bit EFI can only > boot 64-bit applications.Good grief. How is that handled on real systems then: Are there two firmware payloads? Or you can only boot 32-bit OS the legacy way on 64-bit server systems?> X64 is what is the "de facto" standard in the commerical PC/server > world (for example - 2008, Win7 all boot UEFI way only on 64-bit), but > 32-bit UEFI has been used as well and has applications in the > low-power embedded x86 space.I think we''ll just stick with the two config options then -- ovmf-ia32 and ovmf-x64. The correct choice depends on the OS that''s installed, we can''t really auto-detect it, or if we do have that knowledge it will be from within a higher-level management tool which can automatically set this low-level config option appropriately. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Aug-09 21:27 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 09/08/2011 21:54, "Jordan Justen" <jljusten@gmail.com> wrote:>> I assume a native box would only have one UEFI firmware, and that would be >> X64 on an x86/64 box. You must still be able to boot IA32 operating systems >> on the X64 firmware, right? > > Yes, it could technically be booted, if the OS loader was an X64 > application that transitioned to IA32 before starting the OS kernel. > > But, the IA32 OS would then have issues if it wanted to call UEFI > runtime services, which would be X64.Yes, fair enough really, unless you had some dual-payload firmware which installed services appropriate to the OS type it has loaded. But such a thing obviously doesn''t exist. :-) The two config parameters are fine, given how UEFI/OVMF works. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Andrei Warkentin
2011-Aug-09 22:35 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Heya, On Tue, Aug 9, 2011 at 9:39 AM, Ian Campbell <Ian.Campbell@eu.citrix.com> wrote:>> What is the difference between these versions of the VGA BIOS and the existing one? >> I am unsure what is the difference between OVMF VGA BIOS and the existing one in firmware/vgabios. Maybe Andrei or Jordan can give the answer. > > Yes please. >OVMF "VGA bios" is an EFI driver. It is a PE32 (for IA-32) or PE32+ (for X64) binary that contains a framebuffer driver written in C and conforming to the UEFI driver model. It is 64-bit long mode code for X64, and 32-bit pmode code for IA-32. You cannot reuse the legacy 16-bit VGA ROM.>> >> >> >> >> It seems like you only checking the binaries, where is the source and what is its license? >> The source code of OVMF BIOS is available at >> https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/OvmfPkg/ . >> And the license is BSD license. >> >> >> Building the OVMF BIOS needs the environment edk2, whose source code is available at >> https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/ . >> I am afraid OVMF source code can''t be downloaded and built in Xen compiling environment. >> So, I just provide the binary files of OVMF VGA and OVMF BIOS firmware. > > Oh, I see. > > Generally we would like to avoid adding new external projects to the Xen > source tree. Long term we would instead like to see a kind of "meta" > build system which pulls together Xen and the various bits and pieces. > > In the seabios case we decided not to pull any bits seabios into > xen.hg/tools/firmware/seabios/ but rather to provide a configuration > variable which would point to a built seabios.git tree. I think a > similar model would make sense for the OVMF support. IOW OVMF_DIR = "" > by default (OVMF disabled), users who want OVMF can obtain and build > OVMF and then set OVMF_DIR to point this built tree. (eventually this > step will be subsumed into the "meta" build system)I like this.> >> >> >> >> >> With SeaBIOS we moved to a model of loading option ROMs from the >> emulated devices themselves (via the ROM BAR). Could this be used for >> OVMF too? >> Do you mean use the bios->load_roms to load OVMF VGA BIOS instead of loading it in bios_load? > > No. Hardware devices have a special BAR which can be used to map their > option ROM. BIOSes (i.e. real ones on physical machines) use this in > order to map the option ROMs and copy or run them etc. SeaBIOS also > supports this and qemu supports emulating these BARs for the given > devices by providing the contents of a specific file on the host file > system and so we don''t load any VGA BIOS in hvmloader in that case and > just let seabios and qemu take care of it via this mechanism. > > So what I''m suggesting is that OVMF should (and possibly already does) > support this operation and should load the VGA rom itself from the VGA > devices ROM BAR. If the VGABIOS for OVMF needs to be different to what > would be normally need with a legacy BIOS then we can enhance QEMU to > provide the option to request alternative ROM images be used. > > This model makes sense since a device''s option-ROM is tied more to the > specific device than it is to the BIOS etc.I think long-term this is doable and a good idea. Obviously EFI does support loading drivers from PCI ROM, yet right now OVMF just builds in the relevant video drivers into the firmware. Because drivers bind only to specific hardware, it is safe to contain all possible video drivers. I think for now we can just claim no "vga rom" as far hvmloader is concerned. A _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jordan Justen
2011-Aug-09 23:01 UTC
Re: [Xen-devel] [PATCH 2 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Tue, Aug 9, 2011 at 15:35, Andrei Warkentin <andreiw@motorola.com> wrote:> On Tue, Aug 9, 2011 at 9:39 AM, Ian Campbell <Ian.Campbell@eu.citrix.com> wrote: >> No. Hardware devices have a special BAR which can be used to map their >> option ROM. BIOSes (i.e. real ones on physical machines) use this in >> order to map the option ROMs and copy or run them etc. SeaBIOS also >> supports this and qemu supports emulating these BARs for the given >> devices by providing the contents of a specific file on the host file >> system and so we don''t load any VGA BIOS in hvmloader in that case and >> just let seabios and qemu take care of it via this mechanism. >> >> So what I''m suggesting is that OVMF should (and possibly already does) >> support this operation and should load the VGA rom itself from the VGA >> devices ROM BAR. If the VGABIOS for OVMF needs to be different to what >> would be normally need with a legacy BIOS then we can enhance QEMU to >> provide the option to request alternative ROM images be used. >> >> This model makes sense since a device''s option-ROM is tied more to the >> specific device than it is to the BIOS etc. > > I think long-term this is doable and a good idea. Obviously EFI does > support loading drivers from PCI ROM, yet right now OVMF just builds > in the relevant video drivers into the firmware. > Because drivers bind only to specific hardware, it is safe to contain > all possible video drivers. I think for now we can just claim no "vga > rom" as far hvmloader is concerned.Actually, we don''t include the video drivers in the main firmware image. For qemu, vgabios.bin is loaded into RAM at 0xc0000, and we find it there. I think qemu may be moving towards loading vgabios.bin into the PCI ROM-BAR, or maybe they already do. Anyway, it would be best to load the video rom from the PCI device if Xen supports it already. -Jordan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel