This allows a guest to be booted using SeaBIOS directly as its
firmware rather than being loaded indirectly via hvmloader. This is
presented as a proof of concept since it's not obvious yet which the
best approach will be from either Xen or SeaBIOS's point of view.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
Makefile | 2 +-
src/post.c | 5 ++
src/xen.c | 93 ++++++++++++++++++++++++++++++++++++++++++
src/xen.h | 26 ++++++++++++
src/xen/hvm/hvm_info_table.h | 75 +++++++++++++++++++++++++++++++++
5 files changed, 200 insertions(+), 1 deletions(-)
create mode 100644 src/xen.c
create mode 100644 src/xen.h
create mode 100644 src/xen/hvm/hvm_info_table.h
diff --git a/Makefile b/Makefile
index 9affb39..6f12d5a 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ SRC16=$(SRCBOTH) system.c disk.c font.c
SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c dev-i440fx.c \
- pci_region.c
+ pci_region.c xen.c
SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c
cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
diff --git a/src/post.c b/src/post.c
index 7d2b5f2..a2bd2d7 100644
--- a/src/post.c
+++ b/src/post.c
@@ -23,6 +23,7 @@
#include "usb.h" // usb_setup
#include "smbios.h" // smbios_init
#include "paravirt.h" // qemu_cfg_port_probe
+#include "xen.h" // xen_probe_hvm_info
#include "ps2port.h" // ps2port_setup
#include "virtio-blk.h" // virtio_blk_setup
@@ -123,6 +124,9 @@ ram_probe(void)
/* reserve 256KB BIOS area at the end of 4 GB */
add_e820(0xfffc0000, 256*1024, E820_RESERVED);
+
+ if (xen_reserved_size)
+ add_e820(0x100000000ull-xen_reserved_size, xen_reserved_size,
E820_RESERVED);
}
// Don't declare any memory between 0xa0000 and 0x100000
@@ -329,6 +333,7 @@ post(void)
{
// Detect ram and setup internal malloc.
qemu_cfg_port_probe();
+ xen_probe_hvm_info();
ram_probe();
malloc_setup();
diff --git a/src/xen.c b/src/xen.c
new file mode 100644
index 0000000..29e7e68
--- /dev/null
+++ b/src/xen.c
@@ -0,0 +1,93 @@
+// Xen HVM support
+//
+// Copyright (C) 2011 Citrix Systems.
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h"
+#include "xen.h"
+#include "cmos.h"
+
+u32 xen_reserved_size = 0;
+u32 xen_nr_vcpus = 0;
+
+struct hvm_info_table *xen_hvm_info;
+
+static void validate_hvm_info(struct hvm_info_table *t)
+{
+ u8 *ptr = (u8 *)t;
+ u8 sum = 0;
+ int i;
+
+ if ( memcmp(t->signature, "HVM INFO", 8) )
+ panic("Bad hvm info signature\n");
+
+ if ( t->length < sizeof(struct hvm_info_table) )
+ panic("Bad hvm info length\n");
+
+ for ( i = 0; i < t->length; i++ )
+ sum += ptr[i];
+
+ if ( sum != 0 )
+ panic("Bad hvm info checksum\n");
+}
+
+/* Replace possibly erroneous memory-size CMOS fields with correct values. */
+static void cmos_write_memory_size(u32 low_mem_pgend, u32 high_mem_pgend)
+{
+ u32 base_mem = 640, ext_mem, alt_mem;
+ u64 high = high_mem_pgend ? ((u64)high_mem_pgend << 12) - 0x100000000ull :
0ull;
+
+ alt_mem = ext_mem = low_mem_pgend << 12;
+ ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0;
+ if ( ext_mem > 0xffff )
+ ext_mem = 0xffff;
+ alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0;
+
+ /* All BIOSes: conventional memory (CMOS *always* reports 640kB). */
+ outb_cmos((u8)(base_mem >> 0), 0x15);
+ outb_cmos((u8)(base_mem >> 8), 0x16);
+
+ /* All BIOSes: extended memory (1kB chunks above 1MB). */
+ outb_cmos((u8)( ext_mem >> 0), CMOS_MEM_EXTMEM_LOW);
+ outb_cmos((u8)( ext_mem >> 8), CMOS_MEM_EXTMEM_HIGH);
+
+ /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */
+ outb_cmos((u8)( alt_mem >> 0), CMOS_MEM_EXTMEM2_LOW);
+ outb_cmos((u8)( alt_mem >> 8), CMOS_MEM_EXTMEM2_HIGH);
+
+ /* RAM above 4GB */
+ outb_cmos((u8) ((high >> 16) & 0xff), CMOS_MEM_HIGHMEM_LOW);
+ outb_cmos((u8) ((high >> 24) & 0xff), CMOS_MEM_HIGHMEM_MID);
+ outb_cmos((u8) ((high >> 32) & 0xff), CMOS_MEM_HIGHMEM_HIGH);
+}
+
+void xen_probe_hvm_info(void)
+{
+ struct hvm_info_table *t;
+
+ t = (struct hvm_info_table *)HVM_INFO_PADDR;
+
+ validate_hvm_info(t);
+
+ xen_hvm_info = t;
+
+ dprintf(1, "Found HVM info table at %p\n", t);
+ dprintf(1, "Signature %c%c%c%c%c%c%c%c\n",
+ t->signature[0], t->signature[1],
+ t->signature[2], t->signature[3],
+ t->signature[4], t->signature[5],
+ t->signature[6], t->signature[7]);
+ dprintf(1, "Length %d, checksum %x\n", t->length, t->checksum);
+ dprintf(1, "ACPI:%d APIC:%d VCPUS:%d\n",
+ t->acpi_enabled, t->apic_mode, t->nr_vcpus);
+ dprintf(1, "low_mem_pgend: %x\n", t->low_mem_pgend);
+ dprintf(1, "high_mem_pgend: %x\n", t->high_mem_pgend);
+ dprintf(1, "reserved_mem_pgstart: %x\n", t->reserved_mem_pgstart);
+
+ cmos_write_memory_size(t->low_mem_pgend, t->high_mem_pgend);
+
+ xen_reserved_size = (u32)(0x100000000ull -
((u64)t->reserved_mem_pgstart<<12));
+
+ xen_nr_vcpus = t->nr_vcpus;
+}
diff --git a/src/xen.h b/src/xen.h
new file mode 100644
index 0000000..eef9a0e
--- /dev/null
+++ b/src/xen.h
@@ -0,0 +1,26 @@
+#ifndef __XEN_H
+#define __XEN_H
+
+#ifdef CONFIG_XEN
+
+#include "util.h"
+
+#include "xen/hvm/hvm_info_table.h"
+
+void xen_probe_hvm_info(void);
+
+extern u32 xen_reserved_size;
+extern u32 xen_nr_vcpus;
+
+extern struct hvm_info_table *xen_hvm_info;
+
+#else
+
+static voic xen_probe_hvm_info(void) {}
+
+#define xen_reserved_size 0
+#define xen_nr_vcpus 0
+
+#endif
+
+#endif
diff --git a/src/xen/hvm/hvm_info_table.h b/src/xen/hvm/hvm_info_table.h
new file mode 100644
index 0000000..e665883
--- /dev/null
+++ b/src/xen/hvm/hvm_info_table.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ * hvm/hvm_info_table.h
+ *
+ * HVM parameter and information table, written into guest memory map.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
+#define __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__
+
+#define HVM_INFO_PFN 0x09F
+#define HVM_INFO_OFFSET 0x800
+#define HVM_INFO_PADDR ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
+
+/* Maximum we can support with current vLAPIC ID mapping. */
+#define HVM_MAX_VCPUS 128
+
+struct hvm_info_table {
+ char signature[8]; /* "HVM INFO" */
+ u32 length;
+ u8 checksum;
+
+ /* Should firmware build ACPI tables? */
+ u8 acpi_enabled;
+
+ /* Should firmware build APIC descriptors (APIC MADT / MP BIOS)? */
+ u8 apic_mode;
+
+ /* How many CPUs does this domain have? */
+ u32 nr_vcpus;
+
+ /*
+ * MEMORY MAP provided by HVM domain builder.
+ * Notes:
+ * 1. page_to_phys(x) = x << 12
+ * 2. If a field is zero, the corresponding range does not exist.
+ */
+ /*
+ * 0x0 to page_to_phys(low_mem_pgend)-1:
+ * RAM below 4GB (except for VGA hole 0xA0000-0xBFFFF)
+ */
+ u32 low_mem_pgend;
+ /*
+ * page_to_phys(reserved_mem_pgstart) to 0xFFFFFFFF:
+ * Reserved for special memory mappings
+ */
+ u32 reserved_mem_pgstart;
+ /*
+ * 0x100000000 to page_to_phys(high_mem_pgend)-1:
+ * RAM above 4GB
+ */
+ u32 high_mem_pgend;
+
+ /* Bitmap of which CPUs are online at boot time. */
+ u8 vcpu_online[(HVM_MAX_VCPUS + 7)/8];
+};
+
+#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
--
1.7.2.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|