[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] 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@xxxxxxxxx> 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 OVMF 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. 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@xxxxxxxxx > # > > 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@xxxxxxxxx > + * Andrei Warkentin, andreiw@xxxxxxxxxxxx > + * Leendert van Doorn, leendert@xxxxxxxxxxxxxx > + * 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@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |