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
|