WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/2] Basic support for booting directly as Xen HVM fi

To: xen-devel@xxxxxxxxxxxxxxxxxxx, seabios@xxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2/2] Basic support for booting directly as Xen HVM firmware.
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Fri, 13 May 2011 16:59:24 +0100
Cc: Anthony Perard <anthony.perard@xxxxxxxxxx>, Ian Campbell <ian.campbell@xxxxxxxxxx>
Delivery-date: Fri, 13 May 2011 09:10:07 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1305302343.31488.162.camel@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1305302343.31488.162.camel@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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