On Mon, 2011-05-16 at 19:39 -0400, Kevin O'Connor wrote:
> On Mon, May 16, 2011 at 09:44:28AM +0100, Ian Campbell wrote:
> > Sure. I'll change things to do it that way then.
> >
> > As well as CONFIG_XEN should I be adding a xen_present variable which is
> > set dynamically and used as appropriate? If so then is a #ifdef to
> > define it to 0 in the !CONFIG_XEN case (to allow the dead code to be
> > eliminated) necessary?
>
> Thanks.
>
> I'd suggest something like a "int usingXen(void)" inline which reads
> "xen_present". The first couple of lines of usingXen() could do a "if
> (!CONFIG_XEN) return 0".
I've done this, although rather than check a xen_present variable I just
check whether or not the xen_hvm_info ptr is NULL. I also needed to move
the call to xen_probe_hvm_info sooner.
> Though - if the code is as simple as the
> patches you've already sent - then you can leave it on permanently for
> emulators (ie, do "if (CONFIG_COREBOOT)") - I'm not worried about a
> few extra bytes for Xen in the emulator case.
I think once we get a xenbus client and some PV drivers etc it will be
an amount worth saving in the !Xen case.
The following implements all your feedback (I hope). I have squashed it
down into a single commit which supports direct boot.
Ian.
>From 25fdf95c608c73a00a72f0aa1bc72cbd9c03d4ce Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Tue, 17 May 2011 16:43:34 +0100
Subject: [PATCH] Kconfig: Add basic support for booting directly as Xen HVM
firmware
This allows a guest to be booted using SeaBIOS directly as its
firmware rather than being loaded indirectly via hvmloader.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
Makefile | 2 +-
src/Kconfig | 6 +++
src/post.c | 19 ++++++++++
src/shadow.c | 5 ++-
src/xen.c | 57 ++++++++++++++++++++++++++++++++
src/xen.h | 18 ++++++++++
src/xen/hvm/hvm_info_table.h | 75 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 179 insertions(+), 3 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/Kconfig b/src/Kconfig
index 3133d88..69b63b3 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -10,6 +10,12 @@ menu "General Features"
help
Configure as a coreboot payload.
+ config XEN
+ bool "Build for Xen HVM"
+ default n
+ help
+ Configure to be used by xen hvmloader, for a HVM guest.
+
config THREADS
bool "Parallelize hardware init"
default y
diff --git a/src/post.c b/src/post.c
index 7d2b5f2..6703f5e 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
@@ -101,6 +102,22 @@ ram_probe(void)
dprintf(3, "Find memory size\n");
if (CONFIG_COREBOOT) {
coreboot_setup();
+ } else if (usingXen()) {
+ RamSize = xen_hvm_info->low_mem_pgend << 12;
+
+ add_e820(0, RamSize, E820_RAM);
+ if (xen_hvm_info->high_mem_pgend) {
+ RamSizeOver4G = ((u64)xen_hvm_info->high_mem_pgend - 0x100000ull)
<< 12ull;
+ add_e820(0x100000000ull, RamSizeOver4G, E820_RAM);
+ } else {
+ RamSizeOver4G = 0;
+ }
+
+ if (xen_hvm_info->reserved_mem_pgstart) {
+ u32 reserved_base = xen_hvm_info->reserved_mem_pgstart<<12;
+ u64 reserved_size = 0x100000000ull - reserved_base;
+ add_e820(reserved_base, reserved_size, E820_RESERVED);
+ }
} else {
// On emulators, get memory size from nvram.
u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16)
@@ -380,6 +397,8 @@ _start(void)
// This is a soft reboot - invoke a hard reboot.
tryReboot();
+ xen_probe_hvm_info();
+
// Allow writes to modify bios area (0xf0000)
make_bios_writable();
HaveRunPost = 1;
diff --git a/src/shadow.c b/src/shadow.c
index ed530e0..cb39ddf 100644
--- a/src/shadow.c
+++ b/src/shadow.c
@@ -10,6 +10,7 @@
#include "config.h" // CONFIG_*
#include "pci_ids.h" // PCI_VENDOR_ID_INTEL
#include "dev-i440fx.h"
+#include "xen.h" // usingXen
// On the emulators, the bios at 0xf0000 is also at 0xffff0000
#define BIOS_SRC_OFFSET 0xfff00000
@@ -102,7 +103,7 @@ static const struct pci_device_id
dram_controller_make_writable_tbl[] = {
void
make_bios_writable(void)
{
- if (CONFIG_COREBOOT)
+ if (CONFIG_COREBOOT || usingXen())
return;
dprintf(3, "enabling shadow ram\n");
@@ -127,7 +128,7 @@ static const struct pci_device_id
dram_controller_make_readonly_tbl[] = {
void
make_bios_readonly(void)
{
- if (CONFIG_COREBOOT)
+ if (CONFIG_COREBOOT || usingXen())
return;
dprintf(3, "locking shadow ram\n");
diff --git a/src/xen.c b/src/xen.c
new file mode 100644
index 0000000..3b3b79a
--- /dev/null
+++ b/src/xen.c
@@ -0,0 +1,57 @@
+// 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"
+
+struct hvm_info_table *xen_hvm_info = NULL;
+
+static int validate_hvm_info(struct hvm_info_table *t)
+{
+ if ( memcmp(t->signature, "HVM INFO", 8) )
+ return 1;
+
+ if ( t->length < sizeof(struct hvm_info_table) )
+ return 1;
+
+ if (checksum(t, t->length) != 0)
+ return 1;
+
+ return 0;
+}
+
+void xen_probe_hvm_info(void)
+{
+ struct hvm_info_table *t;
+
+ if (!CONFIG_XEN)
+ return;
+
+ dprintf(1, "Probing for Xen HVM info\n");
+
+ t = (struct hvm_info_table *)HVM_INFO_PADDR;
+
+ if (validate_hvm_info(t)) {
+ dprintf(1, "Xen HVM info not found\n");
+ return;
+ }
+
+ 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);
+}
diff --git a/src/xen.h b/src/xen.h
new file mode 100644
index 0000000..723e0c5
--- /dev/null
+++ b/src/xen.h
@@ -0,0 +1,18 @@
+#ifndef __XEN_H
+#define __XEN_H
+
+#include "util.h"
+
+#include "xen/hvm/hvm_info_table.h"
+
+void xen_probe_hvm_info(void);
+
+extern struct hvm_info_table *xen_hvm_info;
+
+static inline int usingXen(void) {
+ if (!CONFIG_XEN)
+ return 0;
+ return (xen_hvm_info != NULL);
+}
+
+#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
|