* [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
@ 2011-07-22 16:23 Bei Guan
2011-07-22 16:38 ` Keir Fraser
2011-07-25 14:03 ` Konrad Rzeszutek Wilk
0 siblings, 2 replies; 10+ messages in thread
From: Bei Guan @ 2011-07-22 16:23 UTC (permalink / raw)
To: Xen Devel; +Cc: edk2-devel, Jordan Justen, Tim Deegan, Andrei Warkentin
[-- Attachment #1.1: Type: text/plain, Size: 15486 bytes --]
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))
[-- Attachment #1.2: Type: text/html, Size: 18417 bytes --]
[-- Attachment #2: ovmf_xen_support.patch --]
[-- Type: text/x-patch, Size: 15315 bytes --]
# HG changeset patch
# User gbtju85@gmail.com
#
Enable Xen-unstable hvmloader to load OVMF BIOS.
It supports OVMF BIOS in IA32 and X86 environment.
Usage:
Add an option field in HVM config file.
# OVMF support. When enabled, hvmloader can load OVMF bios of IA32("ovmf-ia32") and X64("ovmf-x64")
hvmbios = "ovmf-ia32"
#hvmbios = "ovmf-x64"
Note:
Enable the HVM guest ACPI: acpi=1
Use the OVMF to boot into a UEFI-aware OS, such as ubuntu-10.10-desktop-amd64.iso. Just set the "disk" option like this:
disk = [ 'file:/root/<img_name>.img,ioemu:hda,w', 'file:/root/ubuntu-10.10-desktop-amd64.iso,hdc:cdrom,r' ]
Sign-off-by: Bei Guan <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))
diff -r e298ce67777e tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin
Binary file tools/firmware/ovmf/ovmf-ia32-cirrus-vga.bin has changed
diff -r e298ce67777e tools/firmware/ovmf/ovmf-ia32.bin
Binary file tools/firmware/ovmf/ovmf-ia32.bin has changed
diff -r e298ce67777e tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin
Binary file tools/firmware/ovmf/ovmf-x64-cirrus-vga.bin has changed
diff -r e298ce67777e tools/firmware/ovmf/ovmf-x64.bin
Binary file tools/firmware/ovmf/ovmf-x64.bin has changed
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-22 16:23 [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM Bei Guan
@ 2011-07-22 16:38 ` Keir Fraser
2011-07-22 18:38 ` Andrei Warkentin
2011-07-25 14:03 ` Konrad Rzeszutek Wilk
1 sibling, 1 reply; 10+ messages in thread
From: Keir Fraser @ 2011-07-22 16:38 UTC (permalink / raw)
To: Bei Guan, Xen Devel
Cc: edk2-devel, Jordan Justen, Tim Deegan, Andrei Warkentin
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 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@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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-22 16:38 ` Keir Fraser
@ 2011-07-22 18:38 ` Andrei Warkentin
2011-07-23 6:53 ` Keir Fraser
0 siblings, 1 reply; 10+ messages in thread
From: Andrei Warkentin @ 2011-07-22 18:38 UTC (permalink / raw)
To: Keir Fraser; +Cc: edk2-devel, Xen Devel, Jordan Justen, Bei Guan, Tim Deegan
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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-22 18:38 ` Andrei Warkentin
@ 2011-07-23 6:53 ` Keir Fraser
2011-07-23 9:06 ` Keir Fraser
0 siblings, 1 reply; 10+ messages in thread
From: Keir Fraser @ 2011-07-23 6:53 UTC (permalink / raw)
To: Andrei Warkentin
Cc: edk2-devel, Xen Devel, Jordan Justen, Bei Guan, Tim Deegan
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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-23 6:53 ` Keir Fraser
@ 2011-07-23 9:06 ` Keir Fraser
2011-07-23 15:18 ` Bei Guan
0 siblings, 1 reply; 10+ messages in thread
From: Keir Fraser @ 2011-07-23 9:06 UTC (permalink / raw)
To: Andrei Warkentin
Cc: edk2-devel, Xen Devel, Jordan Justen, Bei Guan, Tim Deegan
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
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-23 9:06 ` Keir Fraser
@ 2011-07-23 15:18 ` Bei Guan
2011-07-23 16:50 ` Keir Fraser
0 siblings, 1 reply; 10+ messages in thread
From: Bei Guan @ 2011-07-23 15:18 UTC (permalink / raw)
To: Keir Fraser
Cc: edk2-devel, Xen Devel, Jordan Justen, Tim Deegan,
Andrei Warkentin
[-- Attachment #1.1: Type: text/plain, Size: 2420 bytes --]
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
> >
> >
>
>
>
[-- Attachment #1.2: Type: text/html, Size: 4634 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-23 15:18 ` Bei Guan
@ 2011-07-23 16:50 ` Keir Fraser
0 siblings, 0 replies; 10+ messages in thread
From: Keir Fraser @ 2011-07-23 16:50 UTC (permalink / raw)
To: Bei Guan, Keir Fraser
Cc: edk2-devel, Xen Devel, Jordan Justen, Tim Deegan,
Andrei Warkentin
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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-22 16:23 [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM Bei Guan
2011-07-22 16:38 ` Keir Fraser
@ 2011-07-25 14:03 ` Konrad Rzeszutek Wilk
2011-07-25 14:17 ` Keir Fraser
2011-07-25 15:12 ` Bei Guan
1 sibling, 2 replies; 10+ messages in thread
From: Konrad Rzeszutek Wilk @ 2011-07-25 14:03 UTC (permalink / raw)
To: Bei Guan; +Cc: edk2-devel, Xen Devel, Jordan Justen, Tim Deegan,
Andrei Warkentin
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?
> 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?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-25 14:03 ` Konrad Rzeszutek Wilk
@ 2011-07-25 14:17 ` Keir Fraser
2011-07-25 15:12 ` Bei Guan
1 sibling, 0 replies; 10+ messages in thread
From: Keir Fraser @ 2011-07-25 14:17 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk, Bei Guan
Cc: edk2-devel, Jordan Justen, Xen Devel, Andrei Warkentin,
Tim Deegan
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
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM
2011-07-25 14:03 ` Konrad Rzeszutek Wilk
2011-07-25 14:17 ` Keir Fraser
@ 2011-07-25 15:12 ` Bei Guan
1 sibling, 0 replies; 10+ messages in thread
From: Bei Guan @ 2011-07-25 15:12 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: edk2-devel, Xen Devel, Jordan Justen, Tim Deegan,
Andrei Warkentin
[-- Attachment #1.1: Type: text/plain, Size: 11869 bytes --]
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
[-- Attachment #1.2: Type: text/html, Size: 15607 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-07-25 15:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-22 16:23 [PATCH 1 of 3] Enable UEFI BIOS(OVMF) support in Xen-unstable HVM Bei Guan
2011-07-22 16:38 ` Keir Fraser
2011-07-22 18:38 ` Andrei Warkentin
2011-07-23 6:53 ` Keir Fraser
2011-07-23 9:06 ` Keir Fraser
2011-07-23 15:18 ` Bei Guan
2011-07-23 16:50 ` Keir Fraser
2011-07-25 14:03 ` Konrad Rzeszutek Wilk
2011-07-25 14:17 ` Keir Fraser
2011-07-25 15:12 ` Bei Guan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.