Bei Guan
2011-Jul-22 16:23 UTC
[Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Hi, My name is Bei Guan and I am one of this year''s GSOS students for Tianocore. My project is to enable Xen support in OVMF and the following is about my patch for Xen-unstable. Could you give me some comments? Thank you very much. This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM UEFI support. It supports OVMF BIOS in IA32 and X86 environment. The loaded OVMF BIOS can get Xen SMBIOS and ACPI tables contents inside itself. In order to be clear, I divide the patch into three parts: ovmf_xen_support.patch Enable Xen hvmloader to load OVMF ovmf_firmware.patch OVMF binary files ovmf_xl_xend.patch Add hvmloader/bios xenstore key in libxl and xend 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: You should enable the HVM guest ACPI: acpi=1 You can 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'' ] *ovmf_xen_support.patch:* ------ # HG changeset patch # User gbtju85@gmail.com # diff -r e298ce67777e tools/firmware/hvmloader/Makefile --- a/tools/firmware/hvmloader/Makefile Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/firmware/hvmloader/Makefile Fri Jul 22 23:00:20 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 e298ce67777e tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/firmware/hvmloader/config.h Fri Jul 22 23:00:20 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 { @@ -16,6 +16,9 @@ /* Physical address to load at */ unsigned int bios_address; + /* Custom load function. */ + void (*load)(const struct bios_config *config); + void (*pci_setup)(void); /* ROMS */ int load_roms; unsigned int optionrom_start, optionrom_end; @@ -36,6 +39,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 e298ce67777e tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jul 22 23:00:20 2011 +0800 @@ -360,6 +360,8 @@ #ifdef ENABLE_SEABIOS { "seabios", &seabios_config, }, #endif + { "ovmf-ia32", &ovmf32_config, }, + { "ovmf-x64", &ovmf64_config, }, { NULL, NULL } }; @@ -416,9 +418,13 @@ bios->create_smbios_tables(); } - printf("Loading %s ...\n", bios->name); - memcpy((void *)bios->bios_address, bios->image, - bios->image_size); + if (bios->load) { + bios->load(bios); + } else { + printf("Loading %s ...\n", bios->name); + memcpy((void *)bios->bios_address, bios->image, + bios->image_size); + } if (bios->bios_relocate) bios->bios_relocate(); @@ -451,8 +457,10 @@ vgabios_sz = round_option_rom( (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); break; + case VGA_custom: + break; default: - printf("No emulated VGA adaptor ...\n"); + printf("No emulated VGA adaptor ROM...\n"); break; } diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/firmware/hvmloader/ovmf.c Fri Jul 22 23:00:20 2011 +0800 @@ -0,0 +1,189 @@ +/* + * 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; + + BUG_ON(mem_back_ram(mfn)); + } + + printf("Initialized FD backing pages...\n"); + + /* Copy FD. */ + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); + printf("Load complete!\n"); +} + +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 = ovmf_load, + + .load_roms = 0, + + .optionrom_start = 0, + .optionrom_end = 0, + + .bios_info_setup = NULL, + .bios_info_finish = NULL, + + .bios_relocate = NULL, + + .vm86_setup = ovmf_init_vm86_tss, + .e820_setup = NULL, + + .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 = ovmf_load, + + .load_roms = 0, + + .optionrom_start = 0, + .optionrom_end = 0, + + .bios_info_setup = NULL, + .bios_info_finish = NULL, + + .bios_relocate = NULL, + + .vm86_setup = ovmf_init_vm86_tss, + .e820_setup = NULL, + + .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 e298ce67777e tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/firmware/hvmloader/util.c Fri Jul 22 23:00:20 2011 +0800 @@ -303,12 +303,54 @@ *p = ''\0''; } +/* + * Ensures mfn is backed by an accessible RAM page. + * Returns 0 on success. + */ +int mem_back_ram(xen_pfn_t mfn) +{ + struct xen_add_to_physmap xatp; + struct xen_memory_reservation xmr; + static int over_allocated = 0; + + if ( !over_allocated ) + { + xmr.domid = DOMID_SELF; + xmr.mem_flags = 0; + xmr.extent_order = 0; + xmr.nr_extents = 1; + set_xen_guest_handle(xmr.extent_start, &mfn); + if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 ) + return 0; + over_allocated = 1; + } + + /* + * Couldn''t allocate more memory for domain, + * move an existing physical page from end + * of RAM. + */ + if ( hvm_info->high_mem_pgend ) + { + xatp.idx = --hvm_info->high_mem_pgend; + if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) ) + hvm_info->high_mem_pgend = 0; + } + else + { + xatp.idx = --hvm_info->low_mem_pgend; + } + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_gmfn; + xatp.gpfn = mfn; + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) + BUG(); + return 0; +} + void *mem_alloc(uint32_t size, uint32_t align) { static uint32_t reserve = RESERVED_MEMBASE - 1; - static int over_allocated; - struct xen_add_to_physmap xatp; - struct xen_memory_reservation xmr; xen_pfn_t mfn; uint32_t s, e; @@ -326,35 +368,7 @@ reserve += PAGE_SIZE; mfn = reserve >> PAGE_SHIFT; - /* Try to allocate a brand new page in the reserved area. */ - if ( !over_allocated ) - { - xmr.domid = DOMID_SELF; - xmr.mem_flags = 0; - xmr.extent_order = 0; - xmr.nr_extents = 1; - set_xen_guest_handle(xmr.extent_start, &mfn); - if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 ) - continue; - over_allocated = 1; - } - - /* Otherwise, relocate a page from the ordinary RAM map. */ - if ( hvm_info->high_mem_pgend ) - { - xatp.idx = --hvm_info->high_mem_pgend; - if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) ) - hvm_info->high_mem_pgend = 0; - } - else - { - xatp.idx = --hvm_info->low_mem_pgend; - } - xatp.domid = DOMID_SELF; - xatp.space = XENMAPSPACE_gmfn; - xatp.gpfn = mfn; - if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) - BUG(); + BUG_ON(mem_back_ram(mfn)); } reserve = e; @@ -624,22 +638,24 @@ return table; } -struct shared_info *get_shared_info(void) +static struct shared_info *shared_info = NULL; + +struct shared_info *get_shared_info(void) { - static struct shared_info *shared_info = NULL; struct xen_add_to_physmap xatp; if ( shared_info != NULL ) return shared_info; + /* Guarantee shinfo lives in a safe (reserved) place */ + shared_info = mem_alloc(PAGE_SIZE, PAGE_SIZE); + xatp.domid = DOMID_SELF; xatp.space = XENMAPSPACE_shared_info; xatp.idx = 0; - xatp.gpfn = 0xfffffu; - shared_info = (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); + xatp.gpfn = ((uint32_t) shared_info) >> PAGE_SHIFT; if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); - return shared_info; } diff -r e298ce67777e tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Mon Jul 18 14:38:31 2011 +0100 +++ b/tools/firmware/hvmloader/util.h Fri Jul 22 23:00:20 2011 +0800 @@ -3,6 +3,7 @@ #include <stdarg.h> #include <stdint.h> +#include <xen/memory.h> #include <xen/hvm/hvm_info_table.h> #define __STR(...) #__VA_ARGS__ @@ -164,6 +165,9 @@ int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int vprintf(const char *fmt, va_list ap); +/* Create RAM backing for guest machine frame. */ +int mem_back_ram(xen_pfn_t mfn); + /* Allocate memory in a reserved region below 4GB. */ void *mem_alloc(uint32_t size, uint32_t align); #define virt_to_phys(v) ((unsigned long)(v)) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-22 16:38 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 22/07/2011 17:23, "Bei Guan" <gbtju85@gmail.com> wrote:> Hi, > > My name is Bei Guan and I am one of this year''s GSOS students for Tianocore. > My project is to enable Xen support in OVMF and the following is about my > patch for Xen-unstable. Could you give me some comments? Thank you very much. > > This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM UEFI > support. It supports OVMF BIOS in IA32 and X86 environment. The loaded OVMF > BIOS can get Xen SMBIOS and ACPI tables contents inside itself. > > In order to be clear, I divide the patch into three parts: > ovmf_xen_support.patch Enable Xen hvmloader to load OVMFLooks pretty decent. I wonder why you need to change get_shared_info() -- the existing mapping location is unused at the time hvmloader runs, and you instead map it over the top of a page of RAM. If you want shared_info mapped elsewhere, you can map it wherever you like as soon as your BIOS payload takes over. I''d also need to see what you use mem_back_ram() for, and maybe give it a better name, but I''m not against extracting that functionality into a function for the use of BIOS-specific handlers if the use is sane. -- Keir> ovmf_firmware.patch OVMF binary files > ovmf_xl_xend.patch Add hvmloader/bios xenstore key in libxl and xend > > 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: > You should enable the HVM guest ACPI: acpi=1 > You can 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'' ] > > > ovmf_xen_support.patch: > ------ > > # HG changeset patch > # User gbtju85@gmail.com > # > > diff -r e298ce67777e tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile Fri Jul 22 23:00:20 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 e298ce67777e tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h Fri Jul 22 23:00:20 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 { > @@ -16,6 +16,9 @@ > /* Physical address to load at */ > unsigned int bios_address; > > + /* Custom load function. */ > + void (*load)(const struct bios_config *config); > + void (*pci_setup)(void); > /* ROMS */ > int load_roms; > unsigned int optionrom_start, optionrom_end; > @@ -36,6 +39,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 e298ce67777e tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jul 22 23:00:20 2011 +0800 > @@ -360,6 +360,8 @@ > #ifdef ENABLE_SEABIOS > { "seabios", &seabios_config, }, > #endif > + { "ovmf-ia32", &ovmf32_config, }, > + { "ovmf-x64", &ovmf64_config, }, > { NULL, NULL } > }; > > @@ -416,9 +418,13 @@ > bios->create_smbios_tables(); > } > > - printf("Loading %s ...\n", bios->name); > - memcpy((void *)bios->bios_address, bios->image, > - bios->image_size); > + if (bios->load) { > + bios->load(bios); > + } else { > + printf("Loading %s ...\n", bios->name); > + memcpy((void *)bios->bios_address, bios->image, > + bios->image_size); > + } > > if (bios->bios_relocate) > bios->bios_relocate(); > @@ -451,8 +457,10 @@ > vgabios_sz = round_option_rom( > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > break; > + case VGA_custom: > + break; > default: > - printf("No emulated VGA adaptor ...\n"); > + printf("No emulated VGA adaptor ROM...\n"); > break; > } > > diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c Fri Jul 22 23:00:20 2011 +0800 > @@ -0,0 +1,189 @@ > +/* > + * 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; > + > + BUG_ON(mem_back_ram(mfn)); > + } > + > + printf("Initialized FD backing pages...\n"); > + > + /* Copy FD. */ > + memcpy((void *) OVMF_BEGIN, config->image, OVMF_SIZE); > + printf("Load complete!\n"); > +} > + > +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 = ovmf_load, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .bios_relocate = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + > + .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 = ovmf_load, > + > + .load_roms = 0, > + > + .optionrom_start = 0, > + .optionrom_end = 0, > + > + .bios_info_setup = NULL, > + .bios_info_finish = NULL, > + > + .bios_relocate = NULL, > + > + .vm86_setup = ovmf_init_vm86_tss, > + .e820_setup = NULL, > + > + .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 e298ce67777e tools/firmware/hvmloader/util.c > --- a/tools/firmware/hvmloader/util.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/util.c Fri Jul 22 23:00:20 2011 +0800 > @@ -303,12 +303,54 @@ > *p = ''\0''; > } > > +/* > + * Ensures mfn is backed by an accessible RAM page. > + * Returns 0 on success. > + */ > +int mem_back_ram(xen_pfn_t mfn) > +{ > + struct xen_add_to_physmap xatp; > + struct xen_memory_reservation xmr; > + static int over_allocated = 0; > + > + if ( !over_allocated ) > + { > + xmr.domid = DOMID_SELF; > + xmr.mem_flags = 0; > + xmr.extent_order = 0; > + xmr.nr_extents = 1; > + set_xen_guest_handle(xmr.extent_start, &mfn); > + if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 ) > + return 0; > + over_allocated = 1; > + } > + > + /* > + * Couldn''t allocate more memory for domain, > + * move an existing physical page from end > + * of RAM. > + */ > + if ( hvm_info->high_mem_pgend ) > + { > + xatp.idx = --hvm_info->high_mem_pgend; > + if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) ) > + hvm_info->high_mem_pgend = 0; > + } > + else > + { > + xatp.idx = --hvm_info->low_mem_pgend; > + } > + xatp.domid = DOMID_SELF; > + xatp.space = XENMAPSPACE_gmfn; > + xatp.gpfn = mfn; > + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > + BUG(); > + return 0; > +} > + > void *mem_alloc(uint32_t size, uint32_t align) > { > static uint32_t reserve = RESERVED_MEMBASE - 1; > - static int over_allocated; > - struct xen_add_to_physmap xatp; > - struct xen_memory_reservation xmr; > xen_pfn_t mfn; > uint32_t s, e; > > @@ -326,35 +368,7 @@ > reserve += PAGE_SIZE; > mfn = reserve >> PAGE_SHIFT; > > - /* Try to allocate a brand new page in the reserved area. */ > - if ( !over_allocated ) > - { > - xmr.domid = DOMID_SELF; > - xmr.mem_flags = 0; > - xmr.extent_order = 0; > - xmr.nr_extents = 1; > - set_xen_guest_handle(xmr.extent_start, &mfn); > - if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 ) > - continue; > - over_allocated = 1; > - } > - > - /* Otherwise, relocate a page from the ordinary RAM map. */ > - if ( hvm_info->high_mem_pgend ) > - { > - xatp.idx = --hvm_info->high_mem_pgend; > - if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) ) > - hvm_info->high_mem_pgend = 0; > - } > - else > - { > - xatp.idx = --hvm_info->low_mem_pgend; > - } > - xatp.domid = DOMID_SELF; > - xatp.space = XENMAPSPACE_gmfn; > - xatp.gpfn = mfn; > - if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > - BUG(); > + BUG_ON(mem_back_ram(mfn)); > } > > reserve = e; > @@ -624,22 +638,24 @@ > return table; > } > > -struct shared_info *get_shared_info(void) > +static struct shared_info *shared_info = NULL; > + > +struct shared_info *get_shared_info(void) > { > - static struct shared_info *shared_info = NULL; > struct xen_add_to_physmap xatp; > > if ( shared_info != NULL ) > return shared_info; > > + /* Guarantee shinfo lives in a safe (reserved) place */ > + shared_info = mem_alloc(PAGE_SIZE, PAGE_SIZE); > + > xatp.domid = DOMID_SELF; > xatp.space = XENMAPSPACE_shared_info; > xatp.idx = 0; > - xatp.gpfn = 0xfffffu; > - shared_info = (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); > + xatp.gpfn = ((uint32_t) shared_info) >> PAGE_SHIFT; > if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) > BUG(); > - > return shared_info; > } > > diff -r e298ce67777e tools/firmware/hvmloader/util.h > --- a/tools/firmware/hvmloader/util.h Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/util.h Fri Jul 22 23:00:20 2011 +0800 > @@ -3,6 +3,7 @@ > > #include <stdarg.h> > #include <stdint.h> > +#include <xen/memory.h> > #include <xen/hvm/hvm_info_table.h> > > #define __STR(...) #__VA_ARGS__ > @@ -164,6 +165,9 @@ > int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); > int vprintf(const char *fmt, va_list ap); > > +/* Create RAM backing for guest machine frame. */ > +int mem_back_ram(xen_pfn_t mfn); > + > /* Allocate memory in a reserved region below 4GB. */ > void *mem_alloc(uint32_t size, uint32_t align); > #define virt_to_phys(v) ((unsigned long)(v)) > > > _______________________________________________ > 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
Andrei Warkentin
2011-Jul-22 18:38 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Hi Keir, On Fri, Jul 22, 2011 at 11:38 AM, Keir Fraser <keir.xen@gmail.com> wrote:> Looks pretty decent. I wonder why you need to change get_shared_info() -- > the existing mapping location is unused at the time hvmloader runs, and you > instead map it over the top of a page of RAM. If you want shared_info mapped > elsewhere, you can map it wherever you like as soon as your BIOS payload > takes over. >The problem is that this page lies in an unsafe for OVMF area (right below 4GB). In a typical PC environment, you have the firmware ROM decoding the physical address space right below 4GB, and it also has a chunk (~64-128k) shadowed below 1MB for legacy reasons. The EFI firmware bootstrap code is written with the assumption that it can transfer control to code < 4GB that will finalize the 16->PM-(>LM if 64) transitions and call C code. The get_shared_info page overlaps code we copy up below 4GB. This is why it was moved to a safer region. Effectively, I split the allocator into two portions, since it''s solving two distinct problems - 1) Allocate a safe range of memory - this is used both for RAM allocation and for allocating ranges where "special" pages like get_shared_info page live. 2) Back gmfns outside the allocator range with RAM. Because we need to place the firmware image at a special location (4GB - sizeof(image)), we need to ensure those gmfns actually have backing store.> I''d also need to see what you use mem_back_ram() for, and maybe give it a > better name, but I''m not against extracting that functionality into a > function for the use of BIOS-specific handlers if the use is sane.EFI is different from legacy ROM in that it doesn''t just live below 1MB and the firmware image blob lives < 4GB, so we need to ensure those pages are backed with RAM. Hence, mem_back_ram is simply refactored out from the the old allocator. Thanks, A _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-23 06:53 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 22/07/2011 19:38, "Andrei Warkentin" <andreiw@motorola.com> wrote:> On Fri, Jul 22, 2011 at 11:38 AM, Keir Fraser <keir.xen@gmail.com> wrote: > >> Looks pretty decent. I wonder why you need to change get_shared_info() -- >> the existing mapping location is unused at the time hvmloader runs, and you >> instead map it over the top of a page of RAM. If you want shared_info mapped >> elsewhere, you can map it wherever you like as soon as your BIOS payload >> takes over. >> > > The problem is that this page lies in an unsafe for OVMF area (right > below 4GB). In a typical PC environment, > you have the firmware ROM decoding the physical address space right > below 4GB, and it also has a chunk (~64-128k) shadowed below 1MB for > legacy reasons. The EFI firmware bootstrap code is written with the > assumption that it can transfer control to code < 4GB that will > finalize the 16->PM-(>LM if 64) transitions and call C code. The > get_shared_info page overlaps code we copy up below 4GB. This is why > it was moved to a safer region.Okay, we can work with this easily enough. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-23 09:06 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 23/07/2011 07:53, "Keir Fraser" <keir.xen@gmail.com> wrote:> On 22/07/2011 19:38, "Andrei Warkentin" <andreiw@motorola.com> wrote: > >> On Fri, Jul 22, 2011 at 11:38 AM, Keir Fraser <keir.xen@gmail.com> wrote: >> >>> Looks pretty decent. I wonder why you need to change get_shared_info() -- >>> the existing mapping location is unused at the time hvmloader runs, and you >>> instead map it over the top of a page of RAM. If you want shared_info mapped >>> elsewhere, you can map it wherever you like as soon as your BIOS payload >>> takes over. >>> >> >> The problem is that this page lies in an unsafe for OVMF area (right >> below 4GB). In a typical PC environment, >> you have the firmware ROM decoding the physical address space right >> below 4GB, and it also has a chunk (~64-128k) shadowed below 1MB for >> legacy reasons. The EFI firmware bootstrap code is written with the >> assumption that it can transfer control to code < 4GB that will >> finalize the 16->PM-(>LM if 64) transitions and call C code. The >> get_shared_info page overlaps code we copy up below 4GB. This is why >> it was moved to a safer region. > > Okay, we can work with this easily enough.I''ve applied the util.c changes, or equivalent, to xen-unstable. Further comments on the rest of the hvmloader patch: The added pci_load hook should be removed or used. The printk change on non-detection of a VGA adapter should be removed and proposed as a standalone fix if it makes sense. The bios_load hook is fine, but should replace the ugly bios_relocate hook that was previously hacked in at around the same place. This will simply involve rombios loading both low and high portions of itself, which is really cleaner than what happens currently. This avoids adding yet another hook. -- Keir> -- Keir > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Bei Guan
2011-Jul-23 15:18 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
Hi Keir, Thank you for your comments. 2011/7/23 Keir Fraser <keir@xen.org>> On 23/07/2011 07:53, "Keir Fraser" <keir.xen@gmail.com> wrote: > > > On 22/07/2011 19:38, "Andrei Warkentin" <andreiw@motorola.com> wrote: > > > >> On Fri, Jul 22, 2011 at 11:38 AM, Keir Fraser <keir.xen@gmail.com> > wrote: > >> > >>> Looks pretty decent. I wonder why you need to change get_shared_info() > -- > >>> the existing mapping location is unused at the time hvmloader runs, and > you > >>> instead map it over the top of a page of RAM. If you want shared_info > mapped > >>> elsewhere, you can map it wherever you like as soon as your BIOS > payload > >>> takes over. > >>> > >> > >> The problem is that this page lies in an unsafe for OVMF area (right > >> below 4GB). In a typical PC environment, > >> you have the firmware ROM decoding the physical address space right > >> below 4GB, and it also has a chunk (~64-128k) shadowed below 1MB for > >> legacy reasons. The EFI firmware bootstrap code is written with the > >> assumption that it can transfer control to code < 4GB that will > >> finalize the 16->PM-(>LM if 64) transitions and call C code. The > >> get_shared_info page overlaps code we copy up below 4GB. This is why > >> it was moved to a safer region. > > > > Okay, we can work with this easily enough. > > I''ve applied the util.c changes, or equivalent, to xen-unstable. > > Further comments on the rest of the hvmloader patch: > > The added pci_load hook should be removed or used. >Ok, I have removed this hook.> The printk change on non-detection of a VGA adapter should be removed and > proposed as a standalone fix if it makes sense. >I also removed this change.> The bios_load hook is fine, but should replace the ugly bios_relocate hook > that was previously hacked in at around the same place. This will simply > involve rombios loading both low and high portions of itself, which is > really cleaner than what happens currently. This avoids adding yet another > hook. >Do you mean that put the bios_relocate hook in the "else" statement? Just like this: if (bios->load) { bios->load(bios); } else { printf("Loading %s ...\n", bios->name); memcpy((void *)bios->bios_address, bios->image, bios->image_size); if (bios->bios_relocate) bios->bios_relocate(); } Thanks, Bei Guan> > -- Keir > > > -- Keir > > > > > > >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-23 16:50 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 23/07/2011 16:18, "Bei Guan" <gbtju85@gmail.com> wrote:> Do you mean that put the bios_relocate hook in the "else" statement? Just like > this: > > if (bios->load) { > bios->load(bios); > } else { > printf("Loading %s ...\n", bios->name); > memcpy((void *)bios->bios_address, bios->image, > bios->image_size); > > if (bios->bios_relocate) > bios->bios_relocate(); > }No I mean remove the bios_relocate hook entirely, and modify the rombios handler to use your new hook instead. It should be quite easy. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Konrad Rzeszutek Wilk
2011-Jul-25 14:03 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On Sat, Jul 23, 2011 at 12:23:16AM +0800, Bei Guan wrote:> Hi, > > My name is Bei Guan and I am one of this year''s GSOS students for Tianocore. > My project is to enable Xen support in OVMF and the following is about myWhat does OVMF stand for?> patch for Xen-unstable. Could you give me some comments? Thank you very > much. > > This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM > UEFI support. It supports OVMF BIOS in IA32 and X86 environment. The loaded > OVMF BIOS can get Xen SMBIOS and ACPI tables contents inside itself. > > In order to be clear, I divide the patch into three parts: > ovmf_xen_support.patch Enable Xen hvmloader to load OVMF > ovmf_firmware.patch OVMF binary files > ovmf_xl_xend.patch Add hvmloader/bios xenstore key in libxl and xend > > > 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: > You should enable the HVM guest ACPI: acpi=1 > You can 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'' ] > > > *ovmf_xen_support.patch:* > ------ > > # HG changeset patch > # User gbtju85@gmail.com > # > > diff -r e298ce67777e tools/firmware/hvmloader/Makefile > --- a/tools/firmware/hvmloader/Makefile Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/Makefile Fri Jul 22 23:00:20 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 e298ce67777e tools/firmware/hvmloader/config.h > --- a/tools/firmware/hvmloader/config.h Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/config.h Fri Jul 22 23:00:20 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 { > @@ -16,6 +16,9 @@ > /* Physical address to load at */ > unsigned int bios_address; > > + /* Custom load function. */ > + void (*load)(const struct bios_config *config); > + void (*pci_setup)(void); > /* ROMS */ > int load_roms; > unsigned int optionrom_start, optionrom_end; > @@ -36,6 +39,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 e298ce67777e tools/firmware/hvmloader/hvmloader.c > --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 18 14:38:31 2011 +0100 > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jul 22 23:00:20 2011 +0800 > @@ -360,6 +360,8 @@ > #ifdef ENABLE_SEABIOS > { "seabios", &seabios_config, }, > #endif > + { "ovmf-ia32", &ovmf32_config, }, > + { "ovmf-x64", &ovmf64_config, }, > { NULL, NULL } > }; > > @@ -416,9 +418,13 @@ > bios->create_smbios_tables(); > } > > - printf("Loading %s ...\n", bios->name); > - memcpy((void *)bios->bios_address, bios->image, > - bios->image_size); > + if (bios->load) {You don''t want the printf on this line?> + bios->load(bios); > + } else { > + printf("Loading %s ...\n", bios->name); > + memcpy((void *)bios->bios_address, bios->image, > + bios->image_size); > + } > > if (bios->bios_relocate) > bios->bios_relocate(); > @@ -451,8 +457,10 @@ > vgabios_sz = round_option_rom( > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > break; > + case VGA_custom: > + break; > default: > - printf("No emulated VGA adaptor ...\n"); > + printf("No emulated VGA adaptor ROM...\n"); > break; > } > > diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > +++ b/tools/firmware/hvmloader/ovmf.c Fri Jul 22 23:00:20 2011 +0800 > @@ -0,0 +1,189 @@ > +/* > + * 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.Get rid of the address. That is not neccessary in anymore.> + */ > + > +#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; > + > + BUG_ON(mem_back_ram(mfn)); > + } > + > + printf("Initialized FD backing pages...\n"); > + > + /* Copy FD. */What is FD? _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2011-Jul-25 14:17 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
On 25/07/2011 15:03, "Konrad Rzeszutek Wilk" <konrad.wilk@oracle.com> wrote:> On Sat, Jul 23, 2011 at 12:23:16AM +0800, Bei Guan wrote: >> Hi, >> >> My name is Bei Guan and I am one of this year''s GSOS students for Tianocore. >> My project is to enable Xen support in OVMF and the following is about my > > What does OVMF stand for?Open Virtual Machine Firmware. It looks to be a build/branch of EDK (used to be called Tianocore?) which is Intel''s BSD-licensed UEFI BIOS implementation. Good to have I guess. :-) -- Keir>> patch for Xen-unstable. Could you give me some comments? Thank you very >> much. >> >> This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM >> UEFI support. It supports OVMF BIOS in IA32 and X86 environment. The loaded >> OVMF BIOS can get Xen SMBIOS and ACPI tables contents inside itself. >> >> In order to be clear, I divide the patch into three parts: >> ovmf_xen_support.patch Enable Xen hvmloader to load OVMF >> ovmf_firmware.patch OVMF binary files >> ovmf_xl_xend.patch Add hvmloader/bios xenstore key in libxl and xend >> >> >> 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: >> You should enable the HVM guest ACPI: acpi=1 >> You can 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'' ] >> >> >> *ovmf_xen_support.patch:* >> ------ >> >> # HG changeset patch >> # User gbtju85@gmail.com >> # >> >> diff -r e298ce67777e tools/firmware/hvmloader/Makefile >> --- a/tools/firmware/hvmloader/Makefile Mon Jul 18 14:38:31 2011 +0100 >> +++ b/tools/firmware/hvmloader/Makefile Fri Jul 22 23:00:20 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 e298ce67777e tools/firmware/hvmloader/config.h >> --- a/tools/firmware/hvmloader/config.h Mon Jul 18 14:38:31 2011 +0100 >> +++ b/tools/firmware/hvmloader/config.h Fri Jul 22 23:00:20 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 { >> @@ -16,6 +16,9 @@ >> /* Physical address to load at */ >> unsigned int bios_address; >> >> + /* Custom load function. */ >> + void (*load)(const struct bios_config *config); >> + void (*pci_setup)(void); >> /* ROMS */ >> int load_roms; >> unsigned int optionrom_start, optionrom_end; >> @@ -36,6 +39,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 e298ce67777e tools/firmware/hvmloader/hvmloader.c >> --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 18 14:38:31 2011 +0100 >> +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jul 22 23:00:20 2011 +0800 >> @@ -360,6 +360,8 @@ >> #ifdef ENABLE_SEABIOS >> { "seabios", &seabios_config, }, >> #endif >> + { "ovmf-ia32", &ovmf32_config, }, >> + { "ovmf-x64", &ovmf64_config, }, >> { NULL, NULL } >> }; >> >> @@ -416,9 +418,13 @@ >> bios->create_smbios_tables(); >> } >> >> - printf("Loading %s ...\n", bios->name); >> - memcpy((void *)bios->bios_address, bios->image, >> - bios->image_size); >> + if (bios->load) { > > You don''t want the printf on this line? >> + bios->load(bios); >> + } else { >> + printf("Loading %s ...\n", bios->name); >> + memcpy((void *)bios->bios_address, bios->image, >> + bios->image_size); >> + } >> >> if (bios->bios_relocate) >> bios->bios_relocate(); >> @@ -451,8 +457,10 @@ >> vgabios_sz = round_option_rom( >> (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); >> break; >> + case VGA_custom: >> + break; >> default: >> - printf("No emulated VGA adaptor ...\n"); >> + printf("No emulated VGA adaptor ROM...\n"); >> break; >> } >> >> diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c >> --- /dev/null Thu Jan 01 00:00:00 1970 +0000 >> +++ b/tools/firmware/hvmloader/ovmf.c Fri Jul 22 23:00:20 2011 +0800 >> @@ -0,0 +1,189 @@ >> +/* >> + * 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. > > Get rid of the address. That is not neccessary in anymore. > >> + */ >> + >> +#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; >> + >> + BUG_ON(mem_back_ram(mfn)); >> + } >> + >> + printf("Initialized FD backing pages...\n"); >> + >> + /* Copy FD. */ > > What is FD? > > _______________________________________________ > 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
Bei Guan
2011-Jul-25 15:12 UTC
Re: [Xen-devel] [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011/7/25 Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>> On Sat, Jul 23, 2011 at 12:23:16AM +0800, Bei Guan wrote: > > Hi, > > > > My name is Bei Guan and I am one of this year''s GSOS students for > Tianocore. > > My project is to enable Xen support in OVMF and the following is about my > > What does OVMF stand for? >OVMF stands for Open Virtual Machine Firmware. It is a project to enable support for UEFI within Virtual Machines. It is built upon the EDK II code base and follows the BSD license. You can get more infomation from these websites: https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=OVMF https://sourceforge.net/apps/mediawiki/tianocore/index.php?title=OVMF_FAQ> > patch for Xen-unstable. Could you give me some comments? Thank you very > > much. > > > > This patch can enable Xen-unstable hvmloader to load OVMF BIOS as Xen HVM > > UEFI support. It supports OVMF BIOS in IA32 and X86 environment. The > loaded > > OVMF BIOS can get Xen SMBIOS and ACPI tables contents inside itself. > > > > In order to be clear, I divide the patch into three parts: > > ovmf_xen_support.patch Enable Xen hvmloader to load OVMF > > ovmf_firmware.patch OVMF binary files > > ovmf_xl_xend.patch Add hvmloader/bios xenstore key in libxl and > xend > > > > > > 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: > > You should enable the HVM guest ACPI: acpi=1 > > You can 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'' ] > > > > > > *ovmf_xen_support.patch:* > > ------ > > > > # HG changeset patch > > # User gbtju85@gmail.com > > # > > > > diff -r e298ce67777e tools/firmware/hvmloader/Makefile > > --- a/tools/firmware/hvmloader/Makefile Mon Jul 18 14:38:31 2011 +0100 > > +++ b/tools/firmware/hvmloader/Makefile Fri Jul 22 23:00:20 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 e298ce67777e tools/firmware/hvmloader/config.h > > --- a/tools/firmware/hvmloader/config.h Mon Jul 18 14:38:31 2011 +0100 > > +++ b/tools/firmware/hvmloader/config.h Fri Jul 22 23:00:20 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 { > > @@ -16,6 +16,9 @@ > > /* Physical address to load at */ > > unsigned int bios_address; > > > > + /* Custom load function. */ > > + void (*load)(const struct bios_config *config); > > + void (*pci_setup)(void); > > /* ROMS */ > > int load_roms; > > unsigned int optionrom_start, optionrom_end; > > @@ -36,6 +39,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 e298ce67777e tools/firmware/hvmloader/hvmloader.c > > --- a/tools/firmware/hvmloader/hvmloader.c Mon Jul 18 14:38:31 2011 > +0100 > > +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jul 22 23:00:20 2011 > +0800 > > @@ -360,6 +360,8 @@ > > #ifdef ENABLE_SEABIOS > > { "seabios", &seabios_config, }, > > #endif > > + { "ovmf-ia32", &ovmf32_config, }, > > + { "ovmf-x64", &ovmf64_config, }, > > { NULL, NULL } > > }; > > > > @@ -416,9 +418,13 @@ > > bios->create_smbios_tables(); > > } > > > > - printf("Loading %s ...\n", bios->name); > > - memcpy((void *)bios->bios_address, bios->image, > > - bios->image_size); > > + if (bios->load) { > > You don''t want the printf on this line? >I don''t think we must need this printf on this line. Because in addition to Bios, user maybe need to load other roms, such as VGA rom, in provided bios->load() method. So user can use the printf in bios-load() just before loading the Bios.> > + bios->load(bios); > > + } else { > > + printf("Loading %s ...\n", bios->name); > > + memcpy((void *)bios->bios_address, bios->image, > > + bios->image_size); > > + } > > > > if (bios->bios_relocate) > > bios->bios_relocate(); > > @@ -451,8 +457,10 @@ > > vgabios_sz = round_option_rom( > > (*(uint8_t *)(VGABIOS_PHYSICAL_ADDRESS+2)) * 512); > > break; > > + case VGA_custom: > > + break; > > default: > > - printf("No emulated VGA adaptor ...\n"); > > + printf("No emulated VGA adaptor ROM...\n"); > > break; > > } > > > > diff -r e298ce67777e tools/firmware/hvmloader/ovmf.c > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/tools/firmware/hvmloader/ovmf.c Fri Jul 22 23:00:20 2011 +0800 > > @@ -0,0 +1,189 @@ > > +/* > > + * 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. > > Get rid of the address. That is not neccessary in anymore. >We copied this license from other code files in hvmloader, such as seabios.c, hvmloader.c, and so on. If it''s really neccessary, we will get rid of it in our final patch.> > > + */ > > + > > +#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; > > + > > + BUG_ON(mem_back_ram(mfn)); > > + } > > + > > + printf("Initialized FD backing pages...\n"); > > + > > + /* Copy FD. */ > > What is FD? >FD stands for Firmware Device. It''s a persistent physical repository that contains firmware code and/or data and that may provide nonvolatile storage. For the purposes of this architecture specification, the topology of FDs should be abstracted via frimware volume. Thanks, Bei Guan _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel