All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support
@ 2014-08-08 23:03 Daniel Kiper
  2014-08-08 23:04 ` [PATCH RFC 1/7] xen/x86: Add mbd.h header file Daniel Kiper
                   ` (6 more replies)
  0 siblings, 7 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:03 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Hi,

This patch series breaks multiboot (v1) protocol dependency and adds
multiboot2 support. It laying the foundation for EFI + GRUB2 + Xen
development. Detailed description of ideas and thoughts you will
find in commit message for every patch. If something is not obvious
please drop me a line.

It is RFC patch series so please do not apply it.

I will be preparing for 3 week travel on Monday.
It means that I can be a bit unresponsive.

Daniel

 xen/arch/x86/Makefile             |    1 +
 xen/arch/x86/boot/cmdline.S       |    9 +-
 xen/arch/x86/boot/head.S          |  143 +++++++++++++++++++++++++++----
 xen/arch/x86/boot/reloc.c         |  254 ++++++++++++++++++++++++++++++++++++++++++++----------
 xen/arch/x86/boot/x86_64.S        |   10 ++-
 xen/arch/x86/dmi_scan.c           |    7 +-
 xen/arch/x86/domain_build.c       |   24 +++---
 xen/arch/x86/efi/boot.c           |  216 +++++++++++++++++++++++-----------------------
 xen/arch/x86/efi/efi.h            |    3 -
 xen/arch/x86/efi/runtime.c        |   52 ++++++++---
 xen/arch/x86/init_xbi.c           |  254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/microcode.c          |   39 ++++-----
 xen/arch/x86/mpparse.c            |    9 +-
 xen/arch/x86/platform_hypercall.c |   19 ++--
 xen/arch/x86/setup.c              |  342 ++++++++++++++++++++++--------------------------------------------------
 xen/arch/x86/x86_64/asm-offsets.c |    5 +-
 xen/drivers/acpi/osl.c            |    9 +-
 xen/drivers/video/vesa.c          |    7 +-
 xen/drivers/video/vga.c           |   18 ++--
 xen/include/asm-x86/config.h      |    2 -
 xen/include/asm-x86/e820.h        |    8 --
 xen/include/asm-x86/edd.h         |    6 --
 xen/include/asm-x86/mbd.h         |   70 +++++++++++++++
 xen/include/asm-x86/setup.h       |   10 +--
 xen/include/asm-x86/xbi.h         |  117 +++++++++++++++++++++++++
 xen/include/xen/efi.h             |   10 ---
 xen/include/xen/multiboot2.h      |  386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/vga.h             |   18 ----
 xen/include/xsm/xsm.h             |   14 +--
 xen/xsm/xsm_core.c                |    6 +-
 xen/xsm/xsm_policy.c              |   14 ++-
 31 files changed, 1512 insertions(+), 570 deletions(-)

Daniel Kiper (7):
      xen/x86: Add mbd.h header file
      xen/x86: Add xbi.h header file
      xen: Add multiboot2.h header file
      xen/x86: Migrate to XBI structure
      xen/x86: Add multiboot2 protocol support
      xen: Remove redundant xen/include/xen/vga.h file
      xen/x86: Add new line to the end of graphics mode error message

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-11  9:49   ` Jan Beulich
  2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Define MultiBoot Data (MBD) type. It is used to define variable
which carry over data from multiboot protocol (any version) through
Xen preloader stage. Later all or parts of this data is used
to initialize Xen Boot Info (XBI) structure. XBI is defined
in next patch.

MBD helps to break multiboot (v1) protocol dependency. Using it
we are able to save space on trampoline (we do not allocate space
for unused data what happens in current preloader implementation).
Additionally, we are able to easily add new members to MBD if we
want support new features or protocols.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/include/asm-x86/mbd.h |   70 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 xen/include/asm-x86/mbd.h

diff --git a/xen/include/asm-x86/mbd.h b/xen/include/asm-x86/mbd.h
new file mode 100644
index 0000000..5c20e76
--- /dev/null
+++ b/xen/include/asm-x86/mbd.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MBD_H__
+#define __MBD_H__
+
+/* Module type. */
+typedef struct {
+    u32 start;
+    u32 end;
+
+    /* Pointer to a module command line. */
+    u32 cmdline;
+
+    /* If relocated != 0 then a given module was relocated. */
+    u32 relocated;
+} boot_module_t;
+
+/*
+ * MultiBoot Data (MBD) type. It is used to define variable which
+ * carry over data from multiboot protocol (any version) through
+ * Xen preloader stage. Later all or parts of this data is used
+ * to initialize Xen Boot Info (XBI) structure.
+ */
+typedef struct {
+    /* Pointer to boot loader name. */
+    u32 boot_loader_name;
+
+    /* Pointer to Xen command line. */
+    u32 cmdline;
+
+    /*
+     * Amount of lower memory (in KiB) accordingly to The Multiboot
+     * Specification version 0.6.96.
+     */
+    u32 mem_lower;
+
+    /*
+     * Amount of upper memory (in KiB) accordingly to The Multiboot
+     * Specification version 0.6.96.
+     */
+    u32 mem_upper;
+
+    /* Size (in bytes) of memory map provided by bootloader. */
+    u32 mmap_size;
+
+    /* Pointer to memory map provided by bootloader. */
+    u32 mmap;
+
+    /* Number of modules. */
+    u32 mods_nr;
+
+    /* Pointer to modules description (boot_module_t *). */
+    u32 mods;
+} mbd_t;
+#endif /* __MBD_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
  2014-08-08 23:04 ` [PATCH RFC 1/7] xen/x86: Add mbd.h header file Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-10 16:34   ` Andrew Cooper
                     ` (2 more replies)
  2014-08-08 23:04 ` [PATCH RFC 3/7] xen: Add multiboot2.h " Daniel Kiper
                   ` (4 subsequent siblings)
  6 siblings, 3 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Define Xen Boot Info (XBI) type. This will be used to define variable
used to store data collected by bootloader and preloader. This way
we are able to make most of Xen code bootloader agnostic.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/include/asm-x86/xbi.h |  117 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)
 create mode 100644 xen/include/asm-x86/xbi.h

diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
new file mode 100644
index 0000000..ca9e615
--- /dev/null
+++ b/xen/include/asm-x86/xbi.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __XBI_H__
+#define __XBI_H__
+
+#include <xen/types.h>
+#include <xen/vga.h>
+
+#include <asm/e820.h>
+#include <asm/edd.h>
+#include <asm/mbd.h>
+
+/* Xen Boot Info (XBI) type. */
+typedef struct {
+    /* Boot loader name. */
+    char *boot_loader_name;
+
+    /* Xen command line. */
+    char *cmdline;
+
+    /* Memory map type (source of memory map). */
+    char *mmap_type;
+
+    /*
+     * Amount of upper memory (in KiB) accordingly to The Multiboot
+     * Specification version 0.6.96.
+     */
+    u32 mem_upper;
+
+    /* Number of memory map entries provided by Xen preloader. */
+    int e820map_nr;
+
+    /*
+     * Memory map provided by Xen preloader. It should always point
+     * to an area able to accommodate at least E820MAX entries.
+     */
+    struct e820entry *e820map;
+
+    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
+    unsigned long efi_mmap_size;
+
+    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
+    unsigned long efi_mmap_desc_size;
+
+    /* Pointer to EFI memory map provided by preloader. */
+    void *efi_mmap;
+
+    /* Pointer to MPS. */
+    unsigned long mps;
+
+    /* Pointer to ACPI RSDP. */
+    unsigned long acpi;
+
+    /* Pointer to ACPI 2.0 RSDP. */
+    unsigned long acpi20;
+
+    /* Pointer to SMBIOS. */
+    unsigned long smbios;
+
+    /* Pointer to EFI System Table. */
+    void *efi_system_table;
+
+    /* VGA console info. */
+    struct xen_vga_console_info vga_console_info;
+
+    /* EDID info. */
+    unsigned short edid_caps;
+    unsigned char *edid_info;
+
+    /* Number of EDD entries provided by Xen preloader. */
+    u8 edd_info_nr;
+
+    /* Pointer to EDD info. */
+    struct edd_info *edd_info;
+
+    /* Number of MBR entries provided by Xen preloader. */
+    u8 mbr_signature_nr;
+
+    /* Pointer to MBR info. */
+    struct mbr_signature *mbr_signature;
+
+    /* Number of modules. */
+    unsigned int mods_nr;
+
+    /* Pointer to modules description. */
+    boot_module_t *mods;
+
+    /*
+     * Info about warning occurred during XBI initialization.
+     * NULL if everything went OK.
+     */
+    char *warn_msg;
+
+    /*
+     * Info about error occurred during XBI initialization. NULL if everything
+     * went OK. Otherwise XBI is not fully/properly initialized.
+     */
+    char *err_msg;
+} xbi_t;
+
+extern xbi_t *xbi;
+#endif /* __XBI_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 3/7] xen: Add multiboot2.h header file
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
  2014-08-08 23:04 ` [PATCH RFC 1/7] xen/x86: Add mbd.h header file Daniel Kiper
  2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-11  9:58   ` Jan Beulich
  2014-08-08 23:04 ` [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Define constants and structures which are needed to implement
multiboot2 protocol support.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/include/xen/multiboot2.h |  386 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 386 insertions(+)
 create mode 100644 xen/include/xen/multiboot2.h

diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h
new file mode 100644
index 0000000..ee75c3f
--- /dev/null
+++ b/xen/include/xen/multiboot2.h
@@ -0,0 +1,386 @@
+/*
+ *  Copyright (C) 1999,2003,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *
+ *  multiboot2.h - Multiboot 2 header file.
+ *
+ *  Based on grub-2.00/include/multiboot2.h file.
+ *
+ *  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 ANY
+ *  DEVELOPER OR DISTRIBUTOR 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 __MULTIBOOT2_H__
+#define __MULTIBOOT2_H__
+
+/* The magic field should contain this.  */
+#define MULTIBOOT2_HEADER_MAGIC			0xe85250d6
+
+/* This should be in %eax on x86 architecture.  */
+#define MULTIBOOT2_BOOTLOADER_MAGIC		0x36d76289
+
+/* How many bytes from the start of the file we search for the header.  */
+#define MULTIBOOT2_SEARCH			32768
+
+/* Multiboot 2 header alignment. */
+#define MULTIBOOT2_HEADER_ALIGN			8
+
+/* Alignment of multiboot 2 modules.  */
+#define MULTIBOOT2_MOD_ALIGN			0x00001000
+
+/* Alignment of the multiboot 2 info structure.  */
+#define MULTIBOOT2_INFO_ALIGN			0x00000008
+
+/* Multiboot 2 architectures. */
+#define MULTIBOOT2_ARCHITECTURE_I386	0
+#define MULTIBOOT2_ARCHITECTURE_MIPS32	4
+
+/* Header tag types. */
+#define MULTIBOOT2_HEADER_TAG_END			0
+#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST	1
+#define MULTIBOOT2_HEADER_TAG_ADDRESS			2
+#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS		3
+#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS		4
+#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER		5
+#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN		6
+#define MULTIBOOT2_HEADER_TAG_EFI_BS			7
+
+/* Header tag flags. */
+#define MULTIBOOT2_HEADER_TAG_REQUIRED	0
+#define MULTIBOOT2_HEADER_TAG_OPTIONAL	1
+
+/* Header console tag console_flags. */
+#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED	1
+#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED	2
+
+/* Flags set in the 'flags' member of the multiboot header.  */
+#define MULTIBOOT2_TAG_TYPE_END			0
+#define MULTIBOOT2_TAG_TYPE_CMDLINE		1
+#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME	2
+#define MULTIBOOT2_TAG_TYPE_MODULE		3
+#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO	4
+#define MULTIBOOT2_TAG_TYPE_BOOTDEV		5
+#define MULTIBOOT2_TAG_TYPE_MMAP		6
+#define MULTIBOOT2_TAG_TYPE_VBE			7
+#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER		8
+#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS	9
+#define MULTIBOOT2_TAG_TYPE_APM			10
+#define MULTIBOOT2_TAG_TYPE_EFI32		11
+#define MULTIBOOT2_TAG_TYPE_EFI64		12
+#define MULTIBOOT2_TAG_TYPE_SMBIOS		13
+#define MULTIBOOT2_TAG_TYPE_ACPI_OLD		14
+#define MULTIBOOT2_TAG_TYPE_ACPI_NEW		15
+#define MULTIBOOT2_TAG_TYPE_NETWORK		16
+#define MULTIBOOT2_TAG_TYPE_EFI_MMAP		17
+#define MULTIBOOT2_TAG_TYPE_EFI_BS		18
+
+/* Multiboot 2 tag alignment. */
+#define MULTIBOOT2_TAG_ALIGN			8
+
+/* Memory types. */
+#define MULTIBOOT2_MEMORY_AVAILABLE		1
+#define MULTIBOOT2_MEMORY_RESERVED		2
+#define MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE	3
+#define MULTIBOOT2_MEMORY_NVS			4
+#define MULTIBOOT2_MEMORY_BADRAM		5
+
+/* Framebuffer types. */
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED	0
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB		1
+#define MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT	2
+
+#ifndef __ASSEMBLY__
+typedef struct
+{
+    /* Must be MULTIBOOT2_MAGIC - see above.  */
+    u32 magic;
+
+    /* ISA */
+    u32 architecture;
+
+    /* Total header length.  */
+    u32 header_length;
+
+    /* The above fields plus this one must equal 0 mod 2^32. */
+    u32 checksum;
+} multiboot2_header_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+} multiboot2_header_tag_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 requests[0];
+} multiboot2_header_tag_information_request_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 header_addr;
+    u32 load_addr;
+    u32 load_end_addr;
+    u32 bss_end_addr;
+} multiboot2_header_tag_address_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 entry_addr;
+} multiboot2_header_tag_entry_address_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 console_flags;
+} multiboot2_header_tag_console_flags_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 width;
+    u32 height;
+    u32 depth;
+} multiboot2_header_tag_framebuffer_t;
+
+typedef struct
+{
+    u16 type;
+    u16 flags;
+    u32 size;
+    u32 width;
+    u32 height;
+    u32 depth;
+} multiboot2_header_tag_module_align_t;
+
+typedef struct
+{
+    u8 red;
+    u8 green;
+    u8 blue;
+} multiboot2_color_t;
+
+typedef struct
+{
+    u64 addr;
+    u64 len;
+    u32 type;
+    u32 zero;
+} __attribute__((packed)) multiboot2_memory_map_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+} multiboot2_tag_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    char string[0];
+} multiboot2_tag_string_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 mod_start;
+    u32 mod_end;
+    char cmdline[0];
+} multiboot2_tag_module_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 mem_lower;
+    u32 mem_upper;
+} multiboot2_tag_basic_meminfo_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 biosdev;
+    u32 slice;
+    u32 part;
+} multiboot2_tag_bootdev_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 entry_size;
+    u32 entry_version;
+    multiboot2_memory_map_t entries[0];
+} multiboot2_tag_mmap_t;
+
+typedef struct
+{
+    u8 external_specification[512];
+} multiboot2_vbe_info_block_t;
+
+typedef struct
+{
+    u8 external_specification[256];
+} multiboot2_vbe_mode_info_block_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+
+    u16 vbe_mode;
+    u16 vbe_interface_seg;
+    u16 vbe_interface_off;
+    u16 vbe_interface_len;
+
+    multiboot2_vbe_info_block_t vbe_control_info;
+    multiboot2_vbe_mode_info_block_t vbe_mode_info;
+} multiboot2_tag_vbe_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+
+    u64 framebuffer_addr;
+    u32 framebuffer_pitch;
+    u32 framebuffer_width;
+    u32 framebuffer_height;
+    u8 framebuffer_bpp;
+    u8 framebuffer_type;
+    u16 reserved;
+} multiboot2_tag_framebuffer_common_t;
+
+typedef struct
+{
+    multiboot2_tag_framebuffer_common_t common;
+
+    union
+    {
+        struct
+        {
+            u16 framebuffer_palette_num_colors;
+            multiboot2_color_t framebuffer_palette[0];
+        };
+        struct
+        {
+            u8 framebuffer_red_field_position;
+            u8 framebuffer_red_mask_size;
+            u8 framebuffer_green_field_position;
+            u8 framebuffer_green_mask_size;
+            u8 framebuffer_blue_field_position;
+            u8 framebuffer_blue_mask_size;
+        };
+    };
+} multiboot2_tag_framebuffer_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 num;
+    u32 entsize;
+    u32 shndx;
+    char sections[0];
+} multiboot2_tag_elf_sections_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u16 version;
+    u16 cseg;
+    u32 offset;
+    u16 cseg_16;
+    u16 dseg;
+    u16 flags;
+    u16 cseg_len;
+    u16 cseg_16_len;
+    u16 dseg_len;
+} multiboot2_tag_apm_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 pointer;
+} multiboot2_tag_efi32_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u64 pointer;
+} multiboot2_tag_efi64_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u8 major;
+    u8 minor;
+    u8 reserved[6];
+    u8 tables[0];
+} multiboot2_tag_smbios_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u8 rsdp[0];
+} multiboot2_tag_old_acpi_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u8 rsdp[0];
+} multiboot2_tag_new_acpi_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u8 dhcpack[0];
+} multiboot2_tag_network_t;
+
+typedef struct
+{
+    u32 type;
+    u32 size;
+    u32 descr_size;
+    u32 descr_vers;
+    u8 efi_mmap[0];
+} multiboot2_tag_efi_mmap_t;
+#endif /* __ASSEMBLY__ */
+#endif /* __MULTIBOOT2_H__ */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
                   ` (2 preceding siblings ...)
  2014-08-08 23:04 ` [PATCH RFC 3/7] xen: Add multiboot2.h " Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-09  0:07   ` Roy Franz
  2014-08-10 17:05   ` Andrew Cooper
  2014-08-08 23:04 ` [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support Daniel Kiper
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

We have all constants and structures in place. So, finally break multiboot (v1)
protocol dependency. It means that most of Xen code (excluding preloader)
could be bootloader agnostic and does not need almost any knowledge about
boot protocol. Additionally, we are able to pass all boot data to __start_xen()
in one bucket without any side channels. I do not mention that we are also
able to easily identify boot data in Xen code.

Here is boot data flow for legacy BIOS platform:

  BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
                                                        /
                     -----------------<-----------------
                     \
                      \
                       ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
                      /
             BIOS ->-/

  * multiboot2 is not implemented yet. Look for it in next patch.

Here is boot data flow for EFI platform:

  EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI

WARNING: ARM build could be broken by this patch. We need to agree XBI
integration into ARM. Personally I think that it is worth storing all
data from any bootloader and preloader in XBI on any architecture. This
give a chance to share more code between architectures. However, every
architecture should define its own XBI (in relevant include/asm directory).
Despite that it looks that some parts of it could be common, e.g.  modules
data, command line arguments, boot loader name, EFI data, etc., even if types
would not be the same. So, as it was stated above a lot of code could be
shared among architectures.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/Makefile             |    1 +
 xen/arch/x86/boot/cmdline.S       |    9 +-
 xen/arch/x86/boot/head.S          |   31 ++--
 xen/arch/x86/boot/reloc.c         |  153 ++++++++++++-----
 xen/arch/x86/boot/x86_64.S        |   10 +-
 xen/arch/x86/dmi_scan.c           |    7 +-
 xen/arch/x86/domain_build.c       |   24 +--
 xen/arch/x86/efi/boot.c           |  212 +++++++++++------------
 xen/arch/x86/efi/efi.h            |    3 -
 xen/arch/x86/efi/runtime.c        |   52 ++++--
 xen/arch/x86/init_xbi.c           |  254 +++++++++++++++++++++++++++
 xen/arch/x86/microcode.c          |   39 ++---
 xen/arch/x86/mpparse.c            |    9 +-
 xen/arch/x86/platform_hypercall.c |   19 +--
 xen/arch/x86/setup.c              |  340 +++++++++++--------------------------
 xen/arch/x86/x86_64/asm-offsets.c |    5 +-
 xen/drivers/acpi/osl.c            |    9 +-
 xen/drivers/video/vesa.c          |    5 +-
 xen/drivers/video/vga.c           |   16 +-
 xen/include/asm-x86/config.h      |    2 -
 xen/include/asm-x86/e820.h        |    8 -
 xen/include/asm-x86/edd.h         |    6 -
 xen/include/asm-x86/setup.h       |   10 +-
 xen/include/xen/efi.h             |   10 --
 xen/include/xen/vga.h             |    4 -
 xen/include/xsm/xsm.h             |   14 +-
 xen/xsm/xsm_core.c                |    6 +-
 xen/xsm/xsm_policy.c              |   14 +-
 28 files changed, 723 insertions(+), 549 deletions(-)
 create mode 100644 xen/arch/x86/init_xbi.c

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index c1e244d..bb2264a 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -42,6 +42,7 @@ obj-y += numa.o
 obj-y += pci.o
 obj-y += percpu.o
 obj-y += physdev.o
+obj-y += init_xbi.o
 obj-y += setup.o
 obj-y += shutdown.o
 obj-y += smp.o
diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
index 00687eb..7316011 100644
--- a/xen/arch/x86/boot/cmdline.S
+++ b/xen/arch/x86/boot/cmdline.S
@@ -152,17 +152,14 @@ cmdline_parse_early:
         pusha
 
         /* Bail if there is no command line to parse. */
-        mov     sym_phys(multiboot_ptr),%ebx
-        mov     MB_flags(%ebx),%eax
-        test    $4,%al
-        jz      .Lcmdline_exit
-        mov     MB_cmdline(%ebx),%eax
+        mov     sym_phys(mbd_ptr),%ebx
+        mov     MBD_cmdline(%ebx),%eax
         test    %eax,%eax
         jz      .Lcmdline_exit
 
         /* Check for 'no-real-mode' command-line option. */
         pushl   $sym_phys(.Lno_rm_opt)
-        pushl   MB_cmdline(%ebx)
+        pushl   MBD_cmdline(%ebx)
         call    .Lfind_option
         test    %eax,%eax
         setnz   %al
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 10ecf51..79bce3c 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -86,14 +86,14 @@ __start:
         jne     not_multiboot
 
         /* Set up trampoline segment 64k below EBDA */
-        movzwl  0x40e,%eax          /* EBDA segment */
-        cmp     $0xa000,%eax        /* sanity check (high) */
+        movzwl  0x40e,%ecx          /* EBDA segment */
+        cmp     $0xa000,%ecx        /* sanity check (high) */
         jae     0f
-        cmp     $0x4000,%eax        /* sanity check (low) */
+        cmp     $0x4000,%ecx        /* sanity check (low) */
         jae     1f
 0:
-        movzwl  0x413,%eax          /* use base memory size on failure */
-        shl     $10-4,%eax
+        movzwl  0x413,%ecx          /* use base memory size on failure */
+        shl     $10-4,%ecx
 1:
         /*
          * Compare the value in the BDA with the information from the
@@ -105,22 +105,23 @@ __start:
         cmp     $0x100,%edx         /* is the multiboot value too small? */
         jb      2f                  /* if so, do not use it */
         shl     $10-4,%edx
-        cmp     %eax,%edx           /* compare with BDA value */
-        cmovb   %edx,%eax           /* and use the smaller */
+        cmp     %ecx,%edx           /* compare with BDA value */
+        cmovb   %edx,%ecx           /* and use the smaller */
 
 2:      /* Reserve 64kb for the trampoline */
-        sub     $0x1000,%eax
+        sub     $0x1000,%ecx
 
         /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
-        xor     %al, %al
-        shl     $4, %eax
-        mov     %eax,sym_phys(trampoline_phys)
+        xor     %cl, %cl
+        shl     $4, %ecx
+        mov     %ecx,sym_phys(trampoline_phys)
 
-        /* Save the Multiboot info struct (after relocation) for later use. */
+        /* Save the Multiboot data (after relocation) for later use. */
         mov     $sym_phys(cpu0_stack)+1024,%esp
-        push    %ebx
-        call    reloc
-        mov     %eax,sym_phys(multiboot_ptr)
+        push    %eax                /* Multiboot magic */
+        push    %ebx                /* Multiboot information address */
+        call    reloc               /* %ecx contains trampoline address */
+        mov     %eax,sym_phys(mbd_ptr)
 
         /* Initialize BSS (no nasty surprises!) */
         mov     $sym_phys(__bss_start),%edi
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index fa0fb6b..29f4887 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -1,40 +1,56 @@
-/******************************************************************************
+/*
  * reloc.c
- * 
+ *
  * 32-bit flat memory-map routines for relocating Multiboot structures
  * and modules. This is most easily done early with paging disabled.
- * 
+ *
  * Copyright (c) 2009, Citrix Systems, Inc.
- * 
+ * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
+ *
  * Authors:
  *    Keir Fraser <keir@xen.org>
+ *    Daniel Kiper
  */
 
-/* entered with %eax = BOOT_TRAMPOLINE */
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+typedef unsigned long long u64;
+
+#include "../../../include/xen/multiboot.h"
+#include "../../../include/asm/mbd.h"
+
+/*
+ * __HERE__ IS TRUE ENTRY POINT!!!
+ *
+ * It is entered from xen/arch/x86/boot/head.S with:
+ *   - %eax = MULTIBOOT_MAGIC,
+ *   - %ebx = MULTIBOOT_INFORMATION_ADDRESS,
+ *   - %ecx = BOOT_TRAMPOLINE.
+ */
 asm (
     "    .text                         \n"
     "    .globl _start                 \n"
     "_start:                           \n"
     "    call 1f                       \n"
     "1:  pop  %ebx                     \n"
-    "    mov  %eax,alloc-1b(%ebx)      \n"
-    "    jmp  reloc                    \n"
+    "    mov  %ecx,alloc-1b(%ebx)      \n"
+    "    jmp  __reloc                  \n"
     );
 
-/* This is our data.  Because the code must be relocatable, no BSS is
- * allowed.  All data is accessed PC-relative with inline assembly.
+/*
+ * This is our data. Because the code must be relocatable, no BSS is
+ * allowed. All data is accessed PC-relative with inline assembly.
  */
 asm (
     "alloc:                            \n"
     "    .long 0                       \n"
     );
 
-typedef unsigned int u32;
-#include "../../../include/xen/multiboot.h"
-
-static void *reloc_mbi_struct(void *old, unsigned int bytes)
+static u32 alloc_struct(u32 bytes)
 {
-    void *new;
+    u32 s;
+
     asm(
     "    call 1f                      \n"
     "1:  pop  %%edx                   \n"
@@ -42,58 +58,105 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
     "    sub  %1,%0                   \n"
     "    and  $~15,%0                 \n"
     "    mov  %0,alloc-1b(%%edx)      \n"
-    "    mov  %0,%%edi                \n"
+       : "=&r" (s) : "r" (bytes) : "edx");
+
+    return s;
+}
+
+static void zero_struct(u32 s, u32 bytes)
+{
+    asm volatile(
+    "    cld                          \n"
+    "    xor  %%eax,%%eax             \n"
+    "    rep  stosb                   \n"
+       : "+D" (s), "+c" (bytes) : : "eax");
+}
+
+static u32 copy_struct(u32 src, u32 bytes)
+{
+    u32 dst;
+
+    dst = alloc_struct(bytes);
+
+    asm volatile(
+    "    cld                          \n"
+    "    mov  %2,%%edi                \n"
     "    rep  movsb                   \n"
-       : "=&r" (new), "+c" (bytes), "+S" (old)
-	: : "edx", "edi");
-    return new;
+       : "+S" (src), "+c" (bytes) : "r" (dst) : "edi");
+
+    return dst;
 }
 
-static char *reloc_mbi_string(char *old)
+static u32 copy_string(u32 src)
 {
     char *p;
-    for ( p = old; *p != '\0'; p++ )
+
+    if ( src == 0 )
+        return 0;
+
+    for ( p = (char *)src; *p != '\0'; p++ )
         continue;
-    return reloc_mbi_struct(old, p - old + 1);
+
+    return copy_struct(src, p - (char *)src + 1);
 }
 
-multiboot_info_t *reloc(multiboot_info_t *mbi_old)
+static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
 {
-    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
     int i;
+    module_t *mbi_mods;
+    boot_module_t *mbd_mods;
+
+    if ( mbi->flags & MBI_LOADERNAME )
+        mbd->boot_loader_name = copy_string(mbi->boot_loader_name);
 
     if ( mbi->flags & MBI_CMDLINE )
-        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
+        mbd->cmdline = copy_string(mbi->cmdline);
+
+    if ( mbi->flags & MBI_MEMLIMITS )
+    {
+        mbd->mem_lower = mbi->mem_lower;
+        mbd->mem_upper = mbi->mem_upper;
+    }
+
+    if ( mbi->flags & MBI_MEMMAP )
+    {
+        mbd->mmap_size = mbi->mmap_length;
+        mbd->mmap = copy_struct(mbi->mmap_addr, mbi->mmap_length);
+    }
 
     if ( mbi->flags & MBI_MODULES )
     {
-        module_t *mods = reloc_mbi_struct(
-            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
+        mbd->mods_nr = mbi->mods_count;
+        mbd->mods = alloc_struct(mbi->mods_count * sizeof(boot_module_t));
 
-        mbi->mods_addr = (u32)mods;
+        mbi_mods = (module_t *)mbi->mods_addr;
+        mbd_mods = (boot_module_t *)mbd->mods;
 
         for ( i = 0; i < mbi->mods_count; i++ )
         {
-            if ( mods[i].string )
-                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
+            mbd_mods[i].start = mbi_mods[i].mod_start;
+            mbd_mods[i].end = mbi_mods[i].mod_end;
+            mbd_mods[i].cmdline = copy_string(mbi_mods[i].string);
+            mbd_mods[i].relocated = 0;
         }
     }
 
-    if ( mbi->flags & MBI_MEMMAP )
-        mbi->mmap_addr = (u32)reloc_mbi_struct(
-            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
+    return mbd;
+}
 
-    if ( mbi->flags & MBI_LOADERNAME )
-        mbi->boot_loader_name = (u32)reloc_mbi_string(
-            (char *)mbi->boot_loader_name);
-
-    /* Mask features we don't understand or don't relocate. */
-    mbi->flags &= (MBI_MEMLIMITS |
-                   MBI_BOOTDEV |
-                   MBI_CMDLINE |
-                   MBI_MODULES |
-                   MBI_MEMMAP |
-                   MBI_LOADERNAME);
-
-    return mbi;
+/*
+ * __THIS__ IS NOT ENTRY POINT!!!
+ * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
+ *
+ * It could be a static but then compiler complains:
+ * error: ‘__reloc’ defined but not used.
+ */
+mbd_t *__reloc(void *mbi, u32 mb_magic)
+{
+    mbd_t *mbd;
+
+    mbd = (mbd_t *)alloc_struct(sizeof(mbd_t));
+    zero_struct((u32)mbd, sizeof(mbd_t));
+
+    return mb_mbd(mbd, mbi);
 }
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index bfbafd2..ec39d38 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -29,8 +29,12 @@
         test    %ebx,%ebx
         jnz     start_secondary
 
-        /* Pass off the Multiboot info structure to C land. */
-        mov     multiboot_ptr(%rip),%edi
+        /* Init Xen Boot Info. */
+        mov     mbd_ptr(%rip),%edi
+        call    __init_xbi
+
+        /* Pass off the Xen Boot Info to C land. */
+        movq    %rax,%rdi
         call    __start_xen
         ud2     /* Force a panic (invalid opcode). */
 
@@ -38,7 +42,7 @@
 
         .data
         .align 8
-multiboot_ptr:
+mbd_ptr:
         .long   0
 
         .word   0
diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
index 500133a..cd89360 100644
--- a/xen/arch/x86/dmi_scan.c
+++ b/xen/arch/x86/dmi_scan.c
@@ -12,6 +12,7 @@
 #include <xen/efi.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
+#include <asm/xbi.h>
 
 #define bt_ioremap(b,l)  ((void *)__acpi_map_table(b,l))
 #define bt_iounmap(b,l)  ((void)0)
@@ -215,10 +216,10 @@ static int __init dmi_efi_iterate(void (*decode)(struct dmi_header *))
 	const struct smbios_eps __iomem *p;
 	int ret = -1;
 
-	if (efi.smbios == EFI_INVALID_TABLE_ADDR)
+	if (xbi->smbios == EFI_INVALID_TABLE_ADDR)
 		return -1;
 
-	p = bt_ioremap(efi.smbios, sizeof(eps));
+	p = bt_ioremap(xbi->smbios, sizeof(eps));
 	if (!p)
 		return -1;
 	memcpy_fromio(&eps, p, sizeof(eps));
@@ -227,7 +228,7 @@ static int __init dmi_efi_iterate(void (*decode)(struct dmi_header *))
 	if (memcmp(eps.anchor, "_SM_", 4))
 		return -1;
 
-	p = bt_ioremap(efi.smbios, eps.length);
+	p = bt_ioremap(xbi->smbios, eps.length);
 	if (!p)
 		return -1;
 	if (dmi_checksum(p, eps.length) &&
diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index d4473c1..e35260b 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -751,9 +751,9 @@ static __init void setup_pv_physmap(struct domain *d, unsigned long pgtbl_pfn,
 
 int __init construct_dom0(
     struct domain *d,
-    const module_t *image, unsigned long image_headroom,
-    module_t *initrd,
-    void *(*bootstrap_map)(const module_t *),
+    const boot_module_t *image, unsigned long image_headroom,
+    boot_module_t *initrd,
+    void *(*bootstrap_map)(const boot_module_t *),
     char *cmdline)
 {
     int i, cpu, rc, compatible, compat32, order, machine;
@@ -770,9 +770,9 @@ int __init construct_dom0(
     struct vcpu *v = d->vcpu[0];
     unsigned long long value;
     char *image_base = bootstrap_map(image);
-    unsigned long image_len = image->mod_end;
+    unsigned long image_len = image->end;
     char *image_start = image_base + image_headroom;
-    unsigned long initrd_len = initrd ? initrd->mod_end : 0;
+    unsigned long initrd_len = initrd ? initrd->end : 0;
     l4_pgentry_t *l4tab = NULL, *l4start = NULL;
     l3_pgentry_t *l3tab = NULL, *l3start = NULL;
     l2_pgentry_t *l2tab = NULL, *l2start = NULL;
@@ -987,7 +987,7 @@ int __init construct_dom0(
         initrd_pfn = vinitrd_start ?
                      (vinitrd_start - v_start) >> PAGE_SHIFT :
                      d->tot_pages;
-        initrd_mfn = mfn = initrd->mod_start;
+        initrd_mfn = mfn = initrd->start;
         count = PFN_UP(initrd_len);
         if ( d->arch.physaddr_bitsize &&
              ((mfn + count - 1) >> (d->arch.physaddr_bitsize - PAGE_SHIFT)) )
@@ -1002,12 +1002,12 @@ int __init construct_dom0(
                     free_domheap_pages(page, order);
                     page += 1UL << order;
                 }
-            memcpy(page_to_virt(page), mfn_to_virt(initrd->mod_start),
+            memcpy(page_to_virt(page), mfn_to_virt(initrd->start),
                    initrd_len);
-            mpt_alloc = (paddr_t)initrd->mod_start << PAGE_SHIFT;
+            mpt_alloc = (paddr_t)initrd->start << PAGE_SHIFT;
             init_domheap_pages(mpt_alloc,
                                mpt_alloc + PAGE_ALIGN(initrd_len));
-            initrd->mod_start = initrd_mfn = page_to_mfn(page);
+            initrd->start = initrd_mfn = page_to_mfn(page);
         }
         else
         {
@@ -1015,7 +1015,7 @@ int __init construct_dom0(
                 if ( assign_pages(d, mfn_to_page(mfn++), 0, 0) )
                     BUG();
         }
-        initrd->mod_end = 0;
+        initrd->end = 0;
     }
 
     printk("PHYSICAL MEMORY ARRANGEMENT:\n"
@@ -1026,7 +1026,7 @@ int __init construct_dom0(
                nr_pages - d->tot_pages);
     if ( initrd )
     {
-        mpt_alloc = (paddr_t)initrd->mod_start << PAGE_SHIFT;
+        mpt_alloc = (paddr_t)initrd->start << PAGE_SHIFT;
         printk("\n Init. ramdisk: %"PRIpaddr"->%"PRIpaddr,
                mpt_alloc, mpt_alloc + initrd_len);
     }
@@ -1281,7 +1281,7 @@ int __init construct_dom0(
         if ( pfn >= initrd_pfn )
         {
             if ( pfn < initrd_pfn + PFN_UP(initrd_len) )
-                mfn = initrd->mod_start + (pfn - initrd_pfn);
+                mfn = initrd->start + (pfn - initrd_pfn);
             else
                 mfn -= PFN_UP(initrd_len);
         }
diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index 2b515f2..fea5598 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -9,7 +9,6 @@
 #include <xen/keyhandler.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
-#include <xen/multiboot.h>
 #include <xen/pci_regs.h>
 #include <xen/pfn.h>
 #if EFI_PAGE_SIZE != PAGE_SIZE
@@ -25,6 +24,7 @@
 #undef __ASSEMBLY__
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/xbi.h>
 
 /* Using SetVirtualAddressMap() is incompatible with kexec: */
 #undef USE_SET_VIRTUAL_ADDRESS_MAP
@@ -72,13 +72,12 @@ static struct file __initdata ramdisk;
 static struct file __initdata ucode;
 static struct file __initdata xsm;
 
-static multiboot_info_t __initdata mbi = {
-    .flags = MBI_MODULES | MBI_LOADERNAME
-};
-static module_t __initdata mb_modules[3];
-
 static CHAR16 __initdata newline[] = L"\r\n";
 
+extern unsigned short boot_edid_caps;
+
+extern xbi_t __read_mostly xbi_efi;
+
 #define PrintStr(s) StdOut->OutputString(StdOut, s)
 #define PrintErr(s) StdErr->OutputString(StdErr, s)
 
@@ -255,14 +254,14 @@ static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
     blexit(mesg);
 }
 
-static void __init place_string(u32 *addr, const char *s)
+static void __init place_string_char(char **addr, const char *s)
 {
     static char *__initdata alloc = start;
 
     if ( s && *s )
     {
         size_t len1 = strlen(s) + 1;
-        const char *old = (char *)(long)*addr;
+        const char *old = *addr;
         size_t len2 = *addr ? strlen(old) + 1 : 0;
 
         alloc -= len1 + len2;
@@ -278,7 +277,16 @@ static void __init place_string(u32 *addr, const char *s)
             memcpy(alloc + len1, old, len2);
         }
     }
-    *addr = (long)alloc;
+    *addr = alloc;
+}
+
+static void __init place_string_u32(u32 *addr, const char *s)
+{
+    char *s_new = (char *)(long)*addr;
+
+    place_string_char(&s_new, s);
+
+    *addr = (long)s_new;
 }
 
 static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
@@ -311,7 +319,7 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
                 union string rest = { .w = cmdline };
 
                 --argv;
-                place_string(&mbi.cmdline, w2s(&rest));
+                place_string_char(&xbi_efi.cmdline, w2s(&rest));
                 break;
             }
             else
@@ -480,9 +488,9 @@ static bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
             PrintStr(L"-");
             DisplayUint(file->addr + size, 2 * sizeof(file->addr));
             PrintStr(newline);
-            mb_modules[mbi.mods_count].mod_start = file->addr >> PAGE_SHIFT;
-            mb_modules[mbi.mods_count].mod_end = size;
-            ++mbi.mods_count;
+            xbi_efi.mods[xbi_efi.mods_nr].start = file->addr >> PAGE_SHIFT;
+            xbi_efi.mods[xbi_efi.mods_nr].end = size;
+            ++xbi_efi.mods_nr;
         }
 
         file->size = size;
@@ -568,7 +576,7 @@ static void __init split_value(char *s)
 {
     while ( *s && isspace(*s) )
         ++s;
-    place_string(&mb_modules[mbi.mods_count].string, s);
+    place_string_u32(&xbi_efi.mods[xbi_efi.mods_nr].cmdline, s);
     while ( *s && !isspace(*s) )
         ++s;
     *s = 0;
@@ -884,10 +892,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
                            &cols, &rows) == EFI_SUCCESS )
     {
-        vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
-        vga_console_info.u.text_mode_3.columns = cols;
-        vga_console_info.u.text_mode_3.rows = rows;
-        vga_console_info.u.text_mode_3.font_height = 16;
+        xbi_efi.vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
+        xbi_efi.vga_console_info.u.text_mode_3.columns = cols;
+        xbi_efi.vga_console_info.u.text_mode_3.rows = rows;
+        xbi_efi.vga_console_info.u.text_mode_3.font_height = 16;
     }
 
     size = 0;
@@ -984,7 +992,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         name.s = get_value(&cfg, "global", "ucode");
     if ( name.s )
     {
-        microcode_set_module(mbi.mods_count);
+        microcode_set_module(xbi_efi.mods_nr);
         split_value(name.s);
         read_file(dir_handle, s2w(&name), &ucode);
         efi_bs->FreePool(name.w);
@@ -1000,7 +1008,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 
     name.s = get_value(&cfg, section.s, "options");
     if ( name.s )
-        place_string(&mbi.cmdline, name.s);
+        place_string_char(&xbi_efi.cmdline, name.s);
     /* Insert image name last, as it gets prefixed to the other options. */
     if ( argc )
     {
@@ -1009,7 +1017,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     }
     else
         name.s = "xen";
-    place_string(&mbi.cmdline, name.s);
+    place_string_char(&xbi_efi.cmdline, name.s);
 
     cols = rows = depth = 0;
     if ( !base_video )
@@ -1075,16 +1083,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         }
     }
 
-    if ( mbi.cmdline )
-        mbi.flags |= MBI_CMDLINE;
-    /*
-     * These must not be initialized statically, since the value must
-     * not get relocated when processing base relocations below.
-     */
-    mbi.boot_loader_name = (long)"EFI";
-    mbi.mods_addr = (long)mb_modules;
+    xbi_efi.efi_system_table = SystemTable;
+    xbi_efi.edid_caps = boot_edid_caps;
 
-    place_string(&mbi.mem_upper, NULL);
+    place_string_u32(&xbi_efi.mem_upper, NULL);
 
     /* Collect EDD info. */
     BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
@@ -1102,7 +1104,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     {
         EFI_BLOCK_IO *bio;
         EFI_DEV_PATH_PTR devp;
-        struct edd_info *info = boot_edd_info + boot_edd_info_nr;
+        struct edd_info *info = xbi_efi.edd_info + xbi_efi.edd_info_nr;
         struct edd_device_params *params = &info->edd_device_params;
         enum { root, acpi, pci, ctrlr } state = root;
 
@@ -1111,16 +1113,16 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
              bio->Media->RemovableMedia ||
              bio->Media->LogicalPartition )
             continue;
-        if ( boot_edd_info_nr < EDD_INFO_MAX )
+        if ( xbi_efi.edd_info_nr < EDD_INFO_MAX )
         {
-            info->device = 0x80 + boot_edd_info_nr; /* fake */
+            info->device = 0x80 + xbi_efi.edd_info_nr; /* fake */
             info->version = 0x11;
             params->length = offsetof(struct edd_device_params, dpte_ptr);
             params->number_of_sectors = bio->Media->LastBlock + 1;
             params->bytes_per_sector = bio->Media->BlockSize;
             params->dpte_ptr = ~0;
         }
-        ++boot_edd_info_nr;
+        ++xbi_efi.edd_info_nr;
         status = efi_bs->HandleProtocol(handles[i], &devp_guid,
                                         (void **)&devp);
         if ( EFI_ERROR(status) )
@@ -1133,7 +1135,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                 const u8 *p;
 
             case ACPI_DEVICE_PATH:
-                if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
+                if ( state != root || xbi_efi.edd_info_nr > EDD_INFO_MAX )
                     break;
                 switch ( DevicePathSubType(devp.DevPath) )
                 {
@@ -1152,7 +1154,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             case HARDWARE_DEVICE_PATH:
                 if ( state != acpi ||
                      DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
-                     boot_edd_info_nr > EDD_INFO_MAX )
+                     xbi_efi.edd_info_nr > EDD_INFO_MAX )
                     break;
                 state = pci;
                 edd_put_string(params->host_bus_type, "PCI");
@@ -1160,7 +1162,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                 params->interface_path.pci.function = devp.Pci->Function;
                 break;
             case MESSAGING_DEVICE_PATH:
-                if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
+                if ( state != pci || xbi_efi.edd_info_nr > EDD_INFO_MAX )
                     break;
                 state = ctrlr;
                 switch ( DevicePathSubType(devp.DevPath) )
@@ -1209,15 +1211,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             case MEDIA_DEVICE_PATH:
                 if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
                      devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
-                     boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
+                     xbi_efi.mbr_signature_nr < EDD_MBR_SIG_MAX )
                 {
-                    struct mbr_signature *sig = boot_mbr_signature +
-                                                boot_mbr_signature_nr;
+                    struct mbr_signature *sig = xbi_efi.mbr_signature +
+                                                xbi_efi.mbr_signature_nr;
 
-                    sig->device = 0x80 + boot_edd_info_nr; /* fake */
+                    sig->device = 0x80 + xbi_efi.edd_info_nr; /* fake */
                     memcpy(&sig->signature, devp.HardDrive->Signature,
                            sizeof(sig->signature));
-                    ++boot_mbr_signature_nr;
+                    ++xbi_efi.mbr_signature_nr;
                 }
                 break;
             }
@@ -1225,8 +1227,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     }
     if ( handles )
         efi_bs->FreePool(handles);
-    if ( boot_edd_info_nr > EDD_INFO_MAX )
-        boot_edd_info_nr = EDD_INFO_MAX;
+    if ( xbi_efi.edd_info_nr > EDD_INFO_MAX )
+        xbi_efi.edd_info_nr = EDD_INFO_MAX;
 
     /* XXX Collect EDID info. */
 
@@ -1245,17 +1247,17 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
         static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
 
         if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
-	       efi.acpi20 = (long)efi_ct[i].VendorTable;
+	       xbi_efi.acpi20 = (long)efi_ct[i].VendorTable;
         if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
-	       efi.acpi = (long)efi_ct[i].VendorTable;
+	       xbi_efi.acpi = (long)efi_ct[i].VendorTable;
         if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
-	       efi.mps = (long)efi_ct[i].VendorTable;
+	       xbi_efi.mps = (long)efi_ct[i].VendorTable;
         if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
-	       efi.smbios = (long)efi_ct[i].VendorTable;
+	       xbi_efi.smbios = (long)efi_ct[i].VendorTable;
     }
 
-    if (efi.smbios != EFI_INVALID_TABLE_ADDR)
-        dmi_efi_get_table((void *)(long)efi.smbios);
+    if (xbi_efi.smbios != EFI_INVALID_TABLE_ADDR)
+        dmi_efi_get_table((void *)(long)xbi_efi.smbios);
 
     /* Collect PCI ROM contents. */
     setup_efi_pci();
@@ -1322,40 +1324,40 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             switch ( mode_info->PixelFormat )
             {
             case PixelRedGreenBlueReserved8BitPerColor:
-                vga_console_info.u.vesa_lfb.red_pos = 0;
-                vga_console_info.u.vesa_lfb.red_size = 8;
-                vga_console_info.u.vesa_lfb.green_pos = 8;
-                vga_console_info.u.vesa_lfb.green_size = 8;
-                vga_console_info.u.vesa_lfb.blue_pos = 16;
-                vga_console_info.u.vesa_lfb.blue_size = 8;
-                vga_console_info.u.vesa_lfb.rsvd_pos = 24;
-                vga_console_info.u.vesa_lfb.rsvd_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.red_pos = 0;
+                xbi_efi.vga_console_info.u.vesa_lfb.red_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.green_pos = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.green_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.blue_pos = 16;
+                xbi_efi.vga_console_info.u.vesa_lfb.blue_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos = 24;
+                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size = 8;
                 bpp = 32;
                 break;
             case PixelBlueGreenRedReserved8BitPerColor:
-                vga_console_info.u.vesa_lfb.red_pos = 16;
-                vga_console_info.u.vesa_lfb.red_size = 8;
-                vga_console_info.u.vesa_lfb.green_pos = 8;
-                vga_console_info.u.vesa_lfb.green_size = 8;
-                vga_console_info.u.vesa_lfb.blue_pos = 0;
-                vga_console_info.u.vesa_lfb.blue_size = 8;
-                vga_console_info.u.vesa_lfb.rsvd_pos = 24;
-                vga_console_info.u.vesa_lfb.rsvd_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.red_pos = 16;
+                xbi_efi.vga_console_info.u.vesa_lfb.red_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.green_pos = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.green_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.blue_pos = 0;
+                xbi_efi.vga_console_info.u.vesa_lfb.blue_size = 8;
+                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos = 24;
+                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size = 8;
                 bpp = 32;
                 break;
             case PixelBitMask:
                 bpp = set_color(mode_info->PixelInformation.RedMask, bpp,
-                                &vga_console_info.u.vesa_lfb.red_pos,
-                                &vga_console_info.u.vesa_lfb.red_size);
+                                &xbi_efi.vga_console_info.u.vesa_lfb.red_pos,
+                                &xbi_efi.vga_console_info.u.vesa_lfb.red_size);
                 bpp = set_color(mode_info->PixelInformation.GreenMask, bpp,
-                                &vga_console_info.u.vesa_lfb.green_pos,
-                                &vga_console_info.u.vesa_lfb.green_size);
+                                &xbi_efi.vga_console_info.u.vesa_lfb.green_pos,
+                                &xbi_efi.vga_console_info.u.vesa_lfb.green_size);
                 bpp = set_color(mode_info->PixelInformation.BlueMask, bpp,
-                                &vga_console_info.u.vesa_lfb.blue_pos,
-                                &vga_console_info.u.vesa_lfb.blue_size);
+                                &xbi_efi.vga_console_info.u.vesa_lfb.blue_pos,
+                                &xbi_efi.vga_console_info.u.vesa_lfb.blue_size);
                 bpp = set_color(mode_info->PixelInformation.ReservedMask, bpp,
-                                &vga_console_info.u.vesa_lfb.rsvd_pos,
-                                &vga_console_info.u.vesa_lfb.rsvd_size);
+                                &xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos,
+                                &xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size);
                 if ( bpp > 0 )
                     break;
                 /* fall through */
@@ -1366,37 +1368,37 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             }
         if ( !EFI_ERROR(status) )
         {
-            vga_console_info.video_type = XEN_VGATYPE_EFI_LFB;
-            vga_console_info.u.vesa_lfb.gbl_caps = 2; /* possibly non-VGA */
-            vga_console_info.u.vesa_lfb.width =
+            xbi_efi.vga_console_info.video_type = XEN_VGATYPE_EFI_LFB;
+            xbi_efi.vga_console_info.u.vesa_lfb.gbl_caps = 2; /* possibly non-VGA */
+            xbi_efi.vga_console_info.u.vesa_lfb.width =
                 mode_info->HorizontalResolution;
-            vga_console_info.u.vesa_lfb.height = mode_info->VerticalResolution;
-            vga_console_info.u.vesa_lfb.bits_per_pixel = bpp;
-            vga_console_info.u.vesa_lfb.bytes_per_line =
+            xbi_efi.vga_console_info.u.vesa_lfb.height = mode_info->VerticalResolution;
+            xbi_efi.vga_console_info.u.vesa_lfb.bits_per_pixel = bpp;
+            xbi_efi.vga_console_info.u.vesa_lfb.bytes_per_line =
                 (mode_info->PixelsPerScanLine * bpp + 7) >> 3;
-            vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
-            vga_console_info.u.vesa_lfb.lfb_size =
+            xbi_efi.vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
+            xbi_efi.vga_console_info.u.vesa_lfb.lfb_size =
                 (gop->Mode->FrameBufferSize + 0xffff) >> 16;
         }
     }
 
-    efi_bs->GetMemoryMap(&efi_memmap_size, NULL, &map_key,
-                         &efi_mdesc_size, &mdesc_ver);
-    mbi.mem_upper -= efi_memmap_size;
-    mbi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
-    if ( mbi.mem_upper < xen_phys_start )
-        blexit(L"Out of static memory");
-    efi_memmap = (void *)(long)mbi.mem_upper;
-    status = efi_bs->GetMemoryMap(&efi_memmap_size, efi_memmap, &map_key,
-                                  &efi_mdesc_size, &mdesc_ver);
+    efi_bs->GetMemoryMap(&xbi_efi.efi_mmap_size, NULL, &map_key,
+			 &xbi_efi.efi_mmap_desc_size, &mdesc_ver);
+    xbi_efi.mem_upper -= xbi_efi.efi_mmap_size;
+    xbi_efi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
+    if ( xbi_efi.mem_upper < xen_phys_start )
+        blexit(L"Out of static memory\r\n");
+    xbi_efi.efi_mmap = (void *)(long)xbi_efi.mem_upper;
+    status = efi_bs->GetMemoryMap(&xbi_efi.efi_mmap_size, xbi_efi.efi_mmap, &map_key,
+                                  &xbi_efi.efi_mmap_desc_size, &mdesc_ver);
     if ( EFI_ERROR(status) )
         PrintErrMesg(L"Cannot obtain memory map", status);
 
     /* Populate E820 table and check trampoline area availability. */
-    e = e820map - 1;
-    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+    e = xbi_efi.e820map - 1;
+    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
     {
-        EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+        EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
         u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
         u32 type;
 
@@ -1427,10 +1429,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             type = E820_NVS;
             break;
         }
-        if ( e820nr && type == e->type &&
+        if ( xbi_efi.e820map_nr && type == e->type &&
              desc->PhysicalStart == e->addr + e->size )
             e->size += len;
-        else if ( !len || e820nr >= E820MAX )
+        else if ( !len || xbi_efi.e820map_nr >= E820MAX )
             continue;
         else
         {
@@ -1438,7 +1440,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
             e->addr = desc->PhysicalStart;
             e->size = len;
             e->type = type;
-            ++e820nr;
+            ++xbi_efi.e820map_nr;
         }
     }
     if ( !trampoline_phys )
@@ -1457,7 +1459,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
 #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
     efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
 #endif
-    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
+    xbi_efi.efi_mmap = (void *)xbi_efi.efi_mmap + DIRECTMAP_VIRT_START;
     efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
 
     relocate_image(__XEN_VIRT_START - xen_phys_start);
@@ -1491,7 +1493,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                      [cs] "ir" (__HYPERVISOR_CS),
                      [ds] "r" (__HYPERVISOR_DS),
                      [stkoff] "i" (STACK_SIZE - sizeof(struct cpu_info)),
-                     "D" (&mbi)
+                     "D" (&xbi_efi)
                    : "memory" );
     for( ; ; ); /* not reached */
 }
@@ -1557,9 +1559,9 @@ void __init efi_init_memory(void)
 #endif
 
     printk(XENLOG_INFO "EFI memory map:\n");
-    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
     {
-        EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+        EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
         u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
         unsigned long smfn, emfn;
         unsigned int prot = PAGE_HYPERVISOR;
@@ -1634,8 +1636,8 @@ void __init efi_init_memory(void)
     }
 
 #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
-    efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size,
-                                 mdesc_ver, efi_memmap);
+    efi_rs->SetVirtualAddressMap(xbi_efi.efi_mmap_size, xbi_efi.efi_mmap_desc_size,
+                                 mdesc_ver, xbi_efi.efi_mmap);
 #else
     /* Set up 1:1 page tables to do runtime calls in "physical" mode. */
     efi_l4_pgtable = alloc_xen_pagetable();
@@ -1645,9 +1647,9 @@ void __init efi_init_memory(void)
     copy_mapping(0, max_page, ram_range_valid);
 
     /* Insert non-RAM runtime mappings inside the direct map. */
-    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
     {
-        const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+        const EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
 
         if ( (desc->Attribute & EFI_MEMORY_RUNTIME) &&
              desc->VirtualStart != INVALID_VIRTUAL_ADDRESS &&
diff --git a/xen/arch/x86/efi/efi.h b/xen/arch/x86/efi/efi.h
index a80d5f1..46099de 100644
--- a/xen/arch/x86/efi/efi.h
+++ b/xen/arch/x86/efi/efi.h
@@ -25,9 +25,6 @@ extern const CHAR16 *efi_fw_vendor;
 
 extern EFI_RUNTIME_SERVICES *efi_rs;
 
-extern UINTN efi_memmap_size, efi_mdesc_size;
-extern void *efi_memmap;
-
 extern l4_pgentry_t *efi_l4_pgtable;
 
 extern const struct efi_pci_rom *efi_pci_roms;
diff --git a/xen/arch/x86/efi/runtime.c b/xen/arch/x86/efi/runtime.c
index 166852d..3ef4b5b 100644
--- a/xen/arch/x86/efi/runtime.c
+++ b/xen/arch/x86/efi/runtime.c
@@ -5,6 +5,7 @@
 #include <xen/irq.h>
 #include <xen/time.h>
 #include <asm/mc146818rtc.h>
+#include <asm/xbi.h>
 
 DEFINE_XEN_GUEST_HANDLE(CHAR16);
 
@@ -26,25 +27,50 @@ const CHAR16 *__read_mostly efi_fw_vendor;
 EFI_RUNTIME_SERVICES *__read_mostly efi_rs;
 static DEFINE_SPINLOCK(efi_rs_lock);
 
-UINTN __read_mostly efi_memmap_size;
-UINTN __read_mostly efi_mdesc_size;
-void *__read_mostly efi_memmap;
-
 UINT64 __read_mostly efi_boot_max_var_store_size;
 UINT64 __read_mostly efi_boot_remain_var_store_size;
 UINT64 __read_mostly efi_boot_max_var_size;
 
-struct efi __read_mostly efi = {
-	.acpi   = EFI_INVALID_TABLE_ADDR,
-	.acpi20 = EFI_INVALID_TABLE_ADDR,
-	.mps    = EFI_INVALID_TABLE_ADDR,
-	.smbios = EFI_INVALID_TABLE_ADDR,
-};
-
 l4_pgentry_t *__read_mostly efi_l4_pgtable;
 
 const struct efi_pci_rom *__read_mostly efi_pci_roms;
 
+extern struct e820entry e820map[];
+extern struct edd_info boot_edd_info[];
+extern struct mbr_signature boot_mbr_signature[];
+
+extern unsigned char boot_edid_info[128];
+
+static boot_module_t __read_mostly xbi_mods[3] = {};
+
+xbi_t __read_mostly xbi_efi = {
+    .boot_loader_name = "EFI",
+    .cmdline = NULL,
+    .mmap_type = "EFI",
+    .mem_upper = 0,
+    .e820map_nr = 0,
+    .e820map = e820map,
+    .efi_mmap_size = 0,
+    .efi_mmap_desc_size = 0,
+    .efi_mmap = NULL,
+    .mps = EFI_INVALID_TABLE_ADDR,
+    .acpi = EFI_INVALID_TABLE_ADDR,
+    .acpi20 = EFI_INVALID_TABLE_ADDR,
+    .smbios = EFI_INVALID_TABLE_ADDR,
+    .efi_system_table = NULL,
+    .vga_console_info = {},
+    .edid_caps = 0,
+    .edid_info = boot_edid_info,
+    .edd_info_nr = 0,
+    .edd_info = boot_edd_info,
+    .mbr_signature_nr = 0,
+    .mbr_signature = boot_mbr_signature,
+    .mods_nr = 0,
+    .mods = xbi_mods,
+    .warn_msg = NULL,
+    .err_msg = NULL
+};
+
 unsigned long efi_rs_enter(void)
 {
     static const u16 fcw = FCW_DEFAULT;
@@ -173,9 +199,9 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
         }
         break;
     case XEN_FW_EFI_MEM_INFO:
-        for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
+        for ( i = 0; i < xbi->efi_mmap_size; i += xbi->efi_mmap_desc_size )
         {
-            EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
+            EFI_MEMORY_DESCRIPTOR *desc = xbi->efi_mmap + i;
             u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
 
             if ( info->mem.addr >= desc->PhysicalStart &&
diff --git a/xen/arch/x86/init_xbi.c b/xen/arch/x86/init_xbi.c
new file mode 100644
index 0000000..aebb9cc
--- /dev/null
+++ b/xen/arch/x86/init_xbi.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Some ideas are taken (out) from xen/arch/x86/boot/reloc.c,
+ * xen/arch/x86/efi/boot.c and xen/arch/x86/setup.c.
+ */
+
+#include <xen/types.h>
+#include <xen/cache.h>
+#include <xen/efi.h>
+#include <xen/init.h>
+#include <xen/multiboot.h>
+
+#include <asm/e820.h>
+#include <asm/mbd.h>
+#include <asm/page.h>
+#include <asm/xbi.h>
+
+struct boot_video_info {
+    u8  orig_x;             /* 0x00 */
+    u8  orig_y;             /* 0x01 */
+    u8  orig_video_mode;    /* 0x02 */
+    u8  orig_video_cols;    /* 0x03 */
+    u8  orig_video_lines;   /* 0x04 */
+    u8  orig_video_isVGA;   /* 0x05 */
+    u16 orig_video_points;  /* 0x06 */
+
+    /* VESA graphic mode -- linear frame buffer */
+    u32 capabilities;       /* 0x08 */
+    u16 lfb_linelength;     /* 0x0c */
+    u16 lfb_width;          /* 0x0e */
+    u16 lfb_height;         /* 0x10 */
+    u16 lfb_depth;          /* 0x12 */
+    u32 lfb_base;           /* 0x14 */
+    u32 lfb_size;           /* 0x18 */
+    u8  red_size;           /* 0x1c */
+    u8  red_pos;            /* 0x1d */
+    u8  green_size;         /* 0x1e */
+    u8  green_pos;          /* 0x1f */
+    u8  blue_size;          /* 0x20 */
+    u8  blue_pos;           /* 0x21 */
+    u8  rsvd_size;          /* 0x22 */
+    u8  rsvd_pos;           /* 0x23 */
+    u16 vesapm_seg;         /* 0x24 */
+    u16 vesapm_off;         /* 0x26 */
+    u16 vesa_attrib;        /* 0x28 */
+};
+
+/* These symbols live in the boot trampoline. Access via bootsym(). */
+extern struct e820entry e820map[];
+extern int e820nr;
+extern unsigned int lowmem_kb, highmem_kb;
+
+extern struct boot_video_info boot_vid_info;
+
+extern unsigned short boot_edid_caps;
+extern unsigned char boot_edid_info[128];
+
+extern struct edd_info boot_edd_info[];
+extern u8 boot_edd_info_nr;
+
+extern struct mbr_signature boot_mbr_signature[];
+extern u8 boot_mbr_signature_nr;
+
+static xbi_t __read_mostly xbi_mb = {
+    .boot_loader_name = "UNKNOWN",
+    .cmdline = NULL,
+    .mmap_type = NULL,
+    .mem_upper = 0,
+    .e820map_nr = 0,
+    .e820map = NULL,
+    .efi_mmap_size = 0,
+    .efi_mmap_desc_size = 0,
+    .efi_mmap = NULL,
+    .mps = EFI_INVALID_TABLE_ADDR,
+    .acpi = EFI_INVALID_TABLE_ADDR,
+    .acpi20 = EFI_INVALID_TABLE_ADDR,
+    .smbios = EFI_INVALID_TABLE_ADDR,
+    .efi_system_table = NULL,
+    .vga_console_info = {},
+    .edid_caps = 0,
+    .edid_info = NULL,
+    .edd_info_nr = 0,
+    .edd_info = NULL,
+    .mbr_signature_nr = 0,
+    .mbr_signature = NULL,
+    .mods_nr = 0,
+    .mods = NULL,
+    .warn_msg = NULL,
+    .err_msg = NULL
+};
+
+#define e820_raw bootsym(e820map)
+#define e820_raw_nr bootsym(e820nr)
+
+static void __init init_mmap(xbi_t *xbi, mbd_t *mbd)
+{
+    int bytes = 0;
+    memory_map_t *map;
+
+    if ( e820_raw_nr )
+        xbi->mmap_type = "Xen-e820";
+    else if ( mbd->mmap_size )
+    {
+        xbi->mmap_type = "Multiboot-e820";
+
+        while ( (bytes < mbd->mmap_size) && (e820_raw_nr < E820MAX) )
+        {
+            /*
+             * This is a gross workaround for a BIOS bug. Some bootloaders do
+             * not write e820 map entries into pre-zeroed memory. This is
+             * okay if the BIOS fills in all fields of the map entry, but
+             * some broken BIOSes do not bother to write the high word of
+             * the length field if the length is smaller than 4GB. We
+             * detect and fix this by flagging sections below 4GB that
+             * appear to be larger than 4GB in size.
+             */
+            map = __va(mbd->mmap + bytes);
+
+            if ( !map->base_addr_high && map->length_high )
+            {
+                map->length_high = 0;
+                xbi->warn_msg = "WARNING: Buggy e820 map detected and fixed "
+                                "(truncated length fields).\n";
+            }
+
+            e820_raw[e820_raw_nr].addr =
+                ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
+            e820_raw[e820_raw_nr].size =
+                ((u64)map->length_high << 32) | (u64)map->length_low;
+            e820_raw[e820_raw_nr].type = map->type;
+            e820_raw_nr++;
+
+            bytes += map->size + 4;
+        }
+    }
+    else if ( bootsym(lowmem_kb) )
+    {
+        xbi->mmap_type = "Xen-e801";
+
+        e820_raw[0].addr = 0;
+        e820_raw[0].size = bootsym(lowmem_kb) << 10;
+        e820_raw[0].type = E820_RAM;
+        e820_raw[1].addr = 0x100000;
+        e820_raw[1].size = bootsym(highmem_kb) << 10;
+        e820_raw[1].type = E820_RAM;
+        e820_raw_nr = 2;
+    }
+    else if ( mbd->mem_lower || mbd->mem_upper )
+    {
+        xbi->mmap_type = "Multiboot-e801";
+
+        e820_raw[0].addr = 0;
+        e820_raw[0].size = mbd->mem_lower << 10;
+        e820_raw[0].type = E820_RAM;
+        e820_raw[1].addr = 0x100000;
+        e820_raw[1].size = mbd->mem_upper << 10;
+        e820_raw[1].type = E820_RAM;
+        e820_raw_nr = 2;
+    }
+    else
+    {
+        xbi->err_msg = "Bootloader provided no memory information.\n";
+        return;
+    }
+
+    xbi->mem_upper = mbd->mem_upper;
+
+    xbi->e820map_nr = e820_raw_nr;
+    xbi->e820map = e820_raw;
+}
+
+static void __init init_video_info(xbi_t *xbi)
+{
+    struct boot_video_info *bvi = &bootsym(boot_vid_info);
+
+    if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
+    {
+        xbi->vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
+        xbi->vga_console_info.u.text_mode_3.font_height = bvi->orig_video_points;
+        xbi->vga_console_info.u.text_mode_3.cursor_x = bvi->orig_x;
+        xbi->vga_console_info.u.text_mode_3.cursor_y = bvi->orig_y;
+        xbi->vga_console_info.u.text_mode_3.rows = bvi->orig_video_lines;
+        xbi->vga_console_info.u.text_mode_3.columns = bvi->orig_video_cols;
+    }
+    else if ( bvi->orig_video_isVGA == 0x23 )
+    {
+        xbi->vga_console_info.video_type = XEN_VGATYPE_VESA_LFB;
+        xbi->vga_console_info.u.vesa_lfb.width = bvi->lfb_width;
+        xbi->vga_console_info.u.vesa_lfb.height = bvi->lfb_height;
+        xbi->vga_console_info.u.vesa_lfb.bytes_per_line = bvi->lfb_linelength;
+        xbi->vga_console_info.u.vesa_lfb.bits_per_pixel = bvi->lfb_depth;
+        xbi->vga_console_info.u.vesa_lfb.lfb_base = bvi->lfb_base;
+        xbi->vga_console_info.u.vesa_lfb.lfb_size = bvi->lfb_size;
+        xbi->vga_console_info.u.vesa_lfb.red_pos = bvi->red_pos;
+        xbi->vga_console_info.u.vesa_lfb.red_size = bvi->red_size;
+        xbi->vga_console_info.u.vesa_lfb.green_pos = bvi->green_pos;
+        xbi->vga_console_info.u.vesa_lfb.green_size = bvi->green_size;
+        xbi->vga_console_info.u.vesa_lfb.blue_pos = bvi->blue_pos;
+        xbi->vga_console_info.u.vesa_lfb.blue_size = bvi->blue_size;
+        xbi->vga_console_info.u.vesa_lfb.rsvd_pos = bvi->rsvd_pos;
+        xbi->vga_console_info.u.vesa_lfb.rsvd_size = bvi->rsvd_size;
+        xbi->vga_console_info.u.vesa_lfb.gbl_caps = bvi->capabilities;
+        xbi->vga_console_info.u.vesa_lfb.mode_attrs = bvi->vesa_attrib;
+    }
+
+    xbi->edid_caps = bootsym(boot_edid_caps);
+    xbi->edid_info = bootsym(boot_edid_info);
+}
+
+xbi_t __init *__init_xbi(u32 mbd_ptr)
+{
+    mbd_t *mbd = __va(mbd_ptr);
+
+    if ( mbd->boot_loader_name )
+        xbi_mb.boot_loader_name = __va(mbd->boot_loader_name);
+
+    if ( mbd->cmdline )
+        xbi_mb.cmdline = __va(mbd->cmdline);
+
+    init_mmap(&xbi_mb, mbd);
+
+    if ( xbi_mb.err_msg )
+        goto err;
+
+    init_video_info(&xbi_mb);
+
+    xbi_mb.edd_info_nr = bootsym(boot_edd_info_nr);
+    xbi_mb.edd_info = bootsym(boot_edd_info);
+
+    xbi_mb.mbr_signature_nr = bootsym(boot_mbr_signature_nr);
+    xbi_mb.mbr_signature = bootsym(boot_mbr_signature);
+
+    xbi_mb.mods_nr = mbd->mods_nr;
+    xbi_mb.mods = __va(mbd->mods);
+
+err:
+    return &xbi_mb;
+}
diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
index 091d5d1..9cabf0a 100644
--- a/xen/arch/x86/microcode.c
+++ b/xen/arch/x86/microcode.c
@@ -40,8 +40,8 @@
 #include <asm/setup.h>
 #include <asm/microcode.h>
 
-static module_t __initdata ucode_mod;
-static void *(*__initdata ucode_mod_map)(const module_t *);
+static boot_module_t __initdata ucode_mod;
+static void *(*__initdata ucode_mod_map)(const boot_module_t *);
 static signed int __initdata ucode_mod_idx;
 static bool_t __initdata ucode_mod_forced;
 static cpumask_t __initdata init_mask;
@@ -94,10 +94,9 @@ custom_param("ucode", parse_ucode);
 
 void __init microcode_scan_module(
     unsigned long *module_map,
-    const multiboot_info_t *mbi,
-    void *(*bootmap)(const module_t *))
+    const xbi_t *xbi,
+    void *(*bootmap)(const boot_module_t *))
 {
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
     uint64_t *_blob_start;
     unsigned long _blob_size;
     struct cpio_data cd;
@@ -119,13 +118,13 @@ void __init microcode_scan_module(
     /*
      * Try all modules and see whichever could be the microcode blob.
      */
-    for ( i = 1 /* Ignore dom0 kernel */; i < mbi->mods_count; i++ )
+    for ( i = 1 /* Ignore dom0 kernel */; i < xbi->mods_nr; i++ )
     {
         if ( !test_bit(i, module_map) )
             continue;
 
-        _blob_start = bootmap(&mod[i]);
-        _blob_size = mod[i].mod_end;
+        _blob_start = bootmap(&xbi->mods[i]);
+        _blob_size = xbi->mods[i].end;
         if ( !_blob_start )
         {
             printk("Could not map multiboot module #%d (size: %ld)\n",
@@ -165,21 +164,19 @@ err:
 }
 void __init microcode_grab_module(
     unsigned long *module_map,
-    const multiboot_info_t *mbi,
-    void *(*map)(const module_t *))
+    const xbi_t *xbi,
+    void *(*map)(const boot_module_t *))
 {
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
-
     if ( ucode_mod_idx < 0 )
-        ucode_mod_idx += mbi->mods_count;
-    if ( ucode_mod_idx <= 0 || ucode_mod_idx >= mbi->mods_count ||
+        ucode_mod_idx += xbi->mods_nr;
+    if ( ucode_mod_idx <= 0 || ucode_mod_idx >= xbi->mods_nr ||
          !__test_and_clear_bit(ucode_mod_idx, module_map) )
         goto scan;
-    ucode_mod = mod[ucode_mod_idx];
+    ucode_mod = xbi->mods[ucode_mod_idx];
     ucode_mod_map = map;
 scan:
     if ( ucode_scan )
-        microcode_scan_module(module_map, mbi, map);
+        microcode_scan_module(module_map, xbi, map);
 }
 
 const struct microcode_ops *microcode_ops;
@@ -345,7 +342,7 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len)
 static void __init _do_microcode_update(unsigned long data)
 {
     void *_data = (void *)data;
-    size_t len = ucode_blob.size ? ucode_blob.size : ucode_mod.mod_end;
+    size_t len = ucode_blob.size ? ucode_blob.size : ucode_mod.end;
 
     microcode_update_cpu(_data, len);
     cpumask_set_cpu(smp_processor_id(), &init_mask);
@@ -360,7 +357,7 @@ static int __init microcode_init(void)
     if ( !microcode_ops )
         return 0;
 
-    if ( !ucode_mod.mod_end && !ucode_blob.size )
+    if ( !ucode_mod.end && !ucode_blob.size )
         return 0;
 
     data = ucode_blob.size ? ucode_blob.data : ucode_mod_map(&ucode_mod);
@@ -414,7 +411,7 @@ static int __init microcode_presmp_init(void)
 {
     if ( microcode_ops )
     {
-        if ( ucode_mod.mod_end || ucode_blob.size )
+        if ( ucode_mod.end || ucode_blob.size )
         {
             void *data;
             size_t len;
@@ -427,7 +424,7 @@ static int __init microcode_presmp_init(void)
             }
             else
             {
-                len = ucode_mod.mod_end;
+                len = ucode_mod.end;
                 data = ucode_mod_map(&ucode_mod);
             }
             if ( data )
@@ -447,7 +444,7 @@ static int __init microcode_presmp_init(void)
                     ucode_blob.data = NULL;
                 }
                 else
-                    ucode_mod.mod_end = 0;
+                    ucode_mod.end = 0;
             }
         }
 
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index a38e016..a8bcb14 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -29,6 +29,7 @@
 #include <asm/mpspec.h>
 #include <asm/io_apic.h>
 #include <asm/setup.h>
+#include <asm/xbi.h>
 
 #include <mach_apic.h>
 #include <mach_mpparse.h>
@@ -676,18 +677,18 @@ static void __init efi_check_config(void)
 {
 	struct intel_mp_floating *mpf;
 
-	if (efi.mps == EFI_INVALID_TABLE_ADDR)
+	if (xbi->mps == EFI_INVALID_TABLE_ADDR)
 		return;
 
-	__set_fixmap(FIX_EFI_MPF, PFN_DOWN(efi.mps), __PAGE_HYPERVISOR);
-	mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)efi.mps & (PAGE_SIZE-1));
+	__set_fixmap(FIX_EFI_MPF, PFN_DOWN(xbi->mps), __PAGE_HYPERVISOR);
+	mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)xbi->mps & (PAGE_SIZE-1));
 
 	if (memcmp(mpf->mpf_signature, "_MP_", 4) == 0 &&
 	    mpf->mpf_length == 1 &&
 	    mpf_checksum((void *)mpf, 16) &&
 	    (mpf->mpf_specification == 1 || mpf->mpf_specification == 4)) {
 		smp_found_config = 1;
-		printk(KERN_INFO "SMP MP-table at %08lx\n", efi.mps);
+		printk(KERN_INFO "SMP MP-table at %08lx\n", xbi->mps);
 		mpf_found = mpf;
 	}
 	else
diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 2162811..bbfcfd2 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -30,6 +30,7 @@
 #include <asm/mtrr.h>
 #include <asm/io_apic.h>
 #include <asm/setup.h>
+#include <asm/xbi.h>
 #include "cpu/mtrr/mtrr.h"
 #include <xsm/xsm.h>
 
@@ -208,10 +209,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
             u16 length;
 
             ret = -ESRCH;
-            if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) )
+            if ( op->u.firmware_info.index >= xbi->edd_info_nr )
                 break;
 
-            info = bootsym(boot_edd_info) + op->u.firmware_info.index;
+            info = xbi->edd_info + op->u.firmware_info.index;
 
             /* Transfer the EDD info block. */
             ret = -EFAULT;
@@ -247,10 +248,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
             const struct mbr_signature *sig;
 
             ret = -ESRCH;
-            if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) )
+            if ( op->u.firmware_info.index >= xbi->mbr_signature_nr )
                 break;
 
-            sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index;
+            sig = xbi->mbr_signature + op->u.firmware_info.index;
 
             op->u.firmware_info.u.disk_mbr_signature.device = sig->device;
             op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
@@ -265,13 +266,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
             ret = -ESRCH;
             if ( op->u.firmware_info.index != 0 )
                 break;
-            if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 )
+            if ( *(u32 *)xbi->edid_info == 0x13131313 )
                 break;
 
-            op->u.firmware_info.u.vbeddc_info.capabilities =
-                bootsym(boot_edid_caps);
-            op->u.firmware_info.u.vbeddc_info.edid_transfer_time =
-                bootsym(boot_edid_caps) >> 8;
+            op->u.firmware_info.u.vbeddc_info.capabilities = xbi->edid_caps;
+            op->u.firmware_info.u.vbeddc_info.edid_transfer_time = xbi->edid_caps >> 8;
 
             ret = 0;
             if ( __copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
@@ -279,7 +278,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
                  __copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
                                        u.vbeddc_info.edid_transfer_time) ||
                  copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid,
-                                bootsym(boot_edid_info), 128) )
+                                xbi->edid_info, 128) )
                 ret = -EFAULT;
             break;
         case XEN_FW_EFI_INFO:
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 599cf04..b3bf26a 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -12,7 +12,6 @@
 #include <xen/console.h>
 #include <xen/serial.h>
 #include <xen/trace.h>
-#include <xen/multiboot.h>
 #include <xen/domain_page.h>
 #include <xen/version.h>
 #include <xen/gdbstub.h>
@@ -49,6 +48,7 @@
 #include <xen/cpu.h>
 #include <asm/nmi.h>
 #include <asm/alternative.h>
+#include <asm/xbi.h>
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static bool_t __initdata opt_nosmp;
@@ -93,6 +93,8 @@ unsigned long __initdata highmem_start;
 size_param("highmem-start", highmem_start);
 #endif
 
+xbi_t *xbi;
+
 cpumask_t __read_mostly cpu_present_map;
 
 unsigned long __read_mostly xen_phys_start;
@@ -138,7 +140,7 @@ static void __init parse_acpi_param(char *s)
     }
 }
 
-static const module_t *__initdata initial_images;
+static const boot_module_t *__initdata initial_images;
 static unsigned int __initdata nr_initial_images;
 
 unsigned long __init initial_images_nrpages(void)
@@ -147,7 +149,7 @@ unsigned long __init initial_images_nrpages(void)
     unsigned int i;
 
     for ( nr = i = 0; i < nr_initial_images; ++i )
-        nr += PFN_UP(initial_images[i].mod_end);
+        nr += PFN_UP(initial_images[i].end);
 
     return nr;
 }
@@ -158,10 +160,10 @@ void __init discard_initial_images(void)
 
     for ( i = 0; i < nr_initial_images; ++i )
     {
-        uint64_t start = (uint64_t)initial_images[i].mod_start << PAGE_SHIFT;
+        uint64_t start = (uint64_t)initial_images[i].start << PAGE_SHIFT;
 
         init_domheap_pages(start,
-                           start + PAGE_ALIGN(initial_images[i].mod_end));
+                           start + PAGE_ALIGN(initial_images[i].end));
     }
 
     nr_initial_images = 0;
@@ -262,14 +264,14 @@ static void __init normalise_cpu_order(void)
  * Ensure a given physical memory range is present in the bootstrap mappings.
  * Use superpage mappings to ensure that pagetable memory needn't be allocated.
  */
-static void *__init bootstrap_map(const module_t *mod)
+static void *__init bootstrap_map(const boot_module_t *mod)
 {
     static unsigned long __initdata map_cur = BOOTSTRAP_MAP_BASE;
     uint64_t start, end, mask = (1L << L2_PAGETABLE_SHIFT) - 1;
     void *ret;
 
     if ( system_state != SYS_STATE_early_boot )
-        return mod ? mfn_to_virt(mod->mod_start) : NULL;
+        return mod ? mfn_to_virt(mod->start) : NULL;
 
     if ( !mod )
     {
@@ -278,8 +280,8 @@ static void *__init bootstrap_map(const module_t *mod)
         return NULL;
     }
 
-    start = (uint64_t)mod->mod_start << PAGE_SHIFT;
-    end = start + mod->mod_end;
+    start = (uint64_t)mod->start << PAGE_SHIFT;
+    end = start + mod->end;
     if ( start >= end )
         return NULL;
 
@@ -309,25 +311,25 @@ static void *__init move_memory(
 
     while ( size )
     {
-        module_t mod;
+        boot_module_t mod;
         unsigned int soffs = src & mask;
         unsigned int doffs = dst & mask;
         unsigned int sz;
         void *d, *s;
 
-        mod.mod_start = (src - soffs) >> PAGE_SHIFT;
-        mod.mod_end = soffs + size;
-        if ( mod.mod_end > blksz )
-            mod.mod_end = blksz;
-        sz = mod.mod_end - soffs;
+        mod.start = (src - soffs) >> PAGE_SHIFT;
+        mod.end = soffs + size;
+        if ( mod.end > blksz )
+            mod.end = blksz;
+        sz = mod.end - soffs;
         s = bootstrap_map(&mod);
 
-        mod.mod_start = (dst - doffs) >> PAGE_SHIFT;
-        mod.mod_end = doffs + size;
-        if ( mod.mod_end > blksz )
-            mod.mod_end = blksz;
-        if ( sz > mod.mod_end - doffs )
-            sz = mod.mod_end - doffs;
+        mod.start = (dst - doffs) >> PAGE_SHIFT;
+        mod.end = doffs + size;
+        if ( mod.end > blksz )
+            mod.end = blksz;
+        if ( sz > mod.end - doffs )
+            sz = mod.end - doffs;
         d = bootstrap_map(&mod);
 
         memmove(d + doffs, s + soffs, sz);
@@ -346,7 +348,7 @@ static void *__init move_memory(
 }
 
 static uint64_t __init consider_modules(
-    uint64_t s, uint64_t e, uint32_t size, const module_t *mod,
+    uint64_t s, uint64_t e, uint32_t size, const boot_module_t *mod,
     unsigned int nr_mods, unsigned int this_mod)
 {
     unsigned int i;
@@ -356,8 +358,8 @@ static uint64_t __init consider_modules(
 
     for ( i = 0; i < nr_mods ; ++i )
     {
-        uint64_t start = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
-        uint64_t end = start + PAGE_ALIGN(mod[i].mod_end);
+        uint64_t start = (uint64_t)mod[i].start << PAGE_SHIFT;
+        uint64_t end = start + PAGE_ALIGN(mod[i].end);
 
         if ( i == this_mod )
             continue;
@@ -406,76 +408,6 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn)
 /* A temporary copy of the e820 map that we can mess with during bootstrap. */
 static struct e820map __initdata boot_e820;
 
-struct boot_video_info {
-    u8  orig_x;             /* 0x00 */
-    u8  orig_y;             /* 0x01 */
-    u8  orig_video_mode;    /* 0x02 */
-    u8  orig_video_cols;    /* 0x03 */
-    u8  orig_video_lines;   /* 0x04 */
-    u8  orig_video_isVGA;   /* 0x05 */
-    u16 orig_video_points;  /* 0x06 */
-
-    /* VESA graphic mode -- linear frame buffer */
-    u32 capabilities;       /* 0x08 */
-    u16 lfb_linelength;     /* 0x0c */
-    u16 lfb_width;          /* 0x0e */
-    u16 lfb_height;         /* 0x10 */
-    u16 lfb_depth;          /* 0x12 */
-    u32 lfb_base;           /* 0x14 */
-    u32 lfb_size;           /* 0x18 */
-    u8  red_size;           /* 0x1c */
-    u8  red_pos;            /* 0x1d */
-    u8  green_size;         /* 0x1e */
-    u8  green_pos;          /* 0x1f */
-    u8  blue_size;          /* 0x20 */
-    u8  blue_pos;           /* 0x21 */
-    u8  rsvd_size;          /* 0x22 */
-    u8  rsvd_pos;           /* 0x23 */
-    u16 vesapm_seg;         /* 0x24 */
-    u16 vesapm_off;         /* 0x26 */
-    u16 vesa_attrib;        /* 0x28 */
-};
-extern struct boot_video_info boot_vid_info;
-
-static void __init parse_video_info(void)
-{
-    struct boot_video_info *bvi = &bootsym(boot_vid_info);
-
-    /* The EFI loader fills vga_console_info directly. */
-    if ( efi_enabled )
-        return;
-
-    if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
-    {
-        vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
-        vga_console_info.u.text_mode_3.font_height = bvi->orig_video_points;
-        vga_console_info.u.text_mode_3.cursor_x = bvi->orig_x;
-        vga_console_info.u.text_mode_3.cursor_y = bvi->orig_y;
-        vga_console_info.u.text_mode_3.rows = bvi->orig_video_lines;
-        vga_console_info.u.text_mode_3.columns = bvi->orig_video_cols;
-    }
-    else if ( bvi->orig_video_isVGA == 0x23 )
-    {
-        vga_console_info.video_type = XEN_VGATYPE_VESA_LFB;
-        vga_console_info.u.vesa_lfb.width = bvi->lfb_width;
-        vga_console_info.u.vesa_lfb.height = bvi->lfb_height;
-        vga_console_info.u.vesa_lfb.bytes_per_line = bvi->lfb_linelength;
-        vga_console_info.u.vesa_lfb.bits_per_pixel = bvi->lfb_depth;
-        vga_console_info.u.vesa_lfb.lfb_base = bvi->lfb_base;
-        vga_console_info.u.vesa_lfb.lfb_size = bvi->lfb_size;
-        vga_console_info.u.vesa_lfb.red_pos = bvi->red_pos;
-        vga_console_info.u.vesa_lfb.red_size = bvi->red_size;
-        vga_console_info.u.vesa_lfb.green_pos = bvi->green_pos;
-        vga_console_info.u.vesa_lfb.green_size = bvi->green_size;
-        vga_console_info.u.vesa_lfb.blue_pos = bvi->blue_pos;
-        vga_console_info.u.vesa_lfb.blue_size = bvi->blue_size;
-        vga_console_info.u.vesa_lfb.rsvd_pos = bvi->rsvd_pos;
-        vga_console_info.u.vesa_lfb.rsvd_size = bvi->rsvd_size;
-        vga_console_info.u.vesa_lfb.gbl_caps = bvi->capabilities;
-        vga_console_info.u.vesa_lfb.mode_attrs = bvi->vesa_attrib;
-    }
-}
-
 static void __init kexec_reserve_area(struct e820map *e820)
 {
     unsigned long kdump_start = kexec_crash_area.start;
@@ -540,15 +472,12 @@ static char * __init cmdline_cook(char *p, char *loader_name)
     return p;
 }
 
-void __init noreturn __start_xen(unsigned long mbi_p)
+void __init noreturn __start_xen(xbi_t *xbi_start)
 {
-    char *memmap_type = NULL;
-    char *cmdline, *kextra, *loader;
+    char *cmdline, *kextra;
     unsigned int initrdidx, domcr_flags = DOMCRF_s3_integrity;
-    multiboot_info_t *mbi = __va(mbi_p);
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
     unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
-    int i, j, e820_warn = 0, bytes = 0;
+    int i, j;
     bool_t acpi_boot_table_init_done = 0;
     struct domain *dom0;
     struct ns16550_defaults ns16550 = {
@@ -573,13 +502,16 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     /* Full exception support from here on in. */
 
-    loader = (mbi->flags & MBI_LOADERNAME)
-        ? (char *)__va(mbi->boot_loader_name) : "unknown";
+    if ( !efi_enabled )
+        xbi = xbi_start;
+    else
+    {
+        xbi = __va(xbi_start);
+        xbi->cmdline = __va(xbi->cmdline);
+    }
 
     /* Parse the command-line options. */
-    cmdline = cmdline_cook((mbi->flags & MBI_CMDLINE) ?
-                           __va(mbi->cmdline) : NULL,
-                           loader);
+    cmdline = cmdline_cook(xbi->cmdline, xbi->boot_loader_name);
     if ( (kextra = strstr(cmdline, " -- ")) != NULL )
     {
         /*
@@ -597,8 +529,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * allocing any xenheap structures wanted in lower memory. */
     kexec_early_calculations();
 
-    parse_video_info();
-
     if ( cpu_has_efer )
         rdmsrl(MSR_EFER, this_cpu(efer));
     asm volatile ( "mov %%cr4,%0" : "=r" (this_cpu(cr4)) );
@@ -613,27 +543,33 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     ehci_dbgp_init();
     console_init_preirq();
 
-    printk("Bootloader: %s\n", loader);
+    if ( xbi->err_msg )
+        panic(xbi->err_msg);
+
+    if ( xbi->warn_msg )
+        printk(xbi->warn_msg);
+
+    printk("Bootloader: %s\n", xbi->boot_loader_name);
 
-    printk("Command line: %s\n", cmdline);
+    printk("Command line: %s\n", xbi->cmdline ? xbi->cmdline : "NONE");
 
     printk("Video information:\n");
 
     /* Print VGA display mode information. */
-    switch ( vga_console_info.video_type )
+    switch ( xbi->vga_console_info.video_type )
     {
     case XEN_VGATYPE_TEXT_MODE_3:
         printk(" VGA is text mode %dx%d, font 8x%d\n",
-               vga_console_info.u.text_mode_3.columns,
-               vga_console_info.u.text_mode_3.rows,
-               vga_console_info.u.text_mode_3.font_height);
+               xbi->vga_console_info.u.text_mode_3.columns,
+               xbi->vga_console_info.u.text_mode_3.rows,
+               xbi->vga_console_info.u.text_mode_3.font_height);
         break;
     case XEN_VGATYPE_VESA_LFB:
     case XEN_VGATYPE_EFI_LFB:
         printk(" VGA is graphics mode %dx%d, %d bpp\n",
-               vga_console_info.u.vesa_lfb.width,
-               vga_console_info.u.vesa_lfb.height,
-               vga_console_info.u.vesa_lfb.bits_per_pixel);
+               xbi->vga_console_info.u.vesa_lfb.width,
+               xbi->vga_console_info.u.vesa_lfb.height,
+               xbi->vga_console_info.u.vesa_lfb.bits_per_pixel);
         break;
     default:
         printk(" No VGA detected\n");
@@ -641,15 +577,15 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     }
 
     /* Print VBE/DDC EDID information. */
-    if ( bootsym(boot_edid_caps) != 0x1313 )
+    if ( xbi->edid_caps != 0x1313 )
     {
-        u16 caps = bootsym(boot_edid_caps);
+        u16 caps = xbi->edid_caps;
         printk(" VBE/DDC methods:%s%s%s; ",
                (caps & 1) ? " V1" : "",
                (caps & 2) ? " V2" : "",
                !(caps & 3) ? " none" : "");
         printk("EDID transfer time: %d seconds\n", caps >> 8);
-        if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 )
+        if ( *(u32 *)xbi->edid_info == 0x13131313 )
         {
             printk(" EDID info not retrieved because ");
             if ( !(caps & 3) )
@@ -662,13 +598,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     }
 
     printk("Disc information:\n");
-    printk(" Found %d MBR signatures\n",
-           bootsym(boot_mbr_signature_nr));
-    printk(" Found %d EDD information structures\n",
-           bootsym(boot_edd_info_nr));
+    printk(" Found %d MBR signatures\n", xbi->mbr_signature_nr);
+    printk(" Found %d EDD information structures\n", xbi->edd_info_nr);
 
     /* Check that we have at least one Multiboot module. */
-    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
+    if ( !xbi->mods_nr )
         panic("dom0 kernel not specified. Check bootloader configuration.");
 
     if ( ((unsigned long)cpu0_stack & (STACK_SIZE-1)) != 0 )
@@ -686,77 +620,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         /* Make boot page tables match non-EFI boot. */
         l3_bootmap[l3_table_offset(BOOTSTRAP_MAP_BASE)] =
             l3e_from_paddr(__pa(l2_bootmap), __PAGE_HYPERVISOR);
-
-        memmap_type = loader;
     }
-    else if ( e820_raw_nr != 0 )
-    {
-        memmap_type = "Xen-e820";
-    }
-    else if ( mbi->flags & MBI_MEMMAP )
-    {
-        memmap_type = "Multiboot-e820";
-        while ( (bytes < mbi->mmap_length) && (e820_raw_nr < E820MAX) )
-        {
-            memory_map_t *map = __va(mbi->mmap_addr + bytes);
-
-            /*
-             * This is a gross workaround for a BIOS bug. Some bootloaders do
-             * not write e820 map entries into pre-zeroed memory. This is
-             * okay if the BIOS fills in all fields of the map entry, but
-             * some broken BIOSes do not bother to write the high word of
-             * the length field if the length is smaller than 4GB. We
-             * detect and fix this by flagging sections below 4GB that
-             * appear to be larger than 4GB in size.
-             */
-            if ( (map->base_addr_high == 0) && (map->length_high != 0) )
-            {
-                if ( !e820_warn )
-                {
-                    printk("WARNING: Buggy e820 map detected and fixed "
-                           "(truncated length fields).\n");
-                    e820_warn = 1;
-                }
-                map->length_high = 0;
-            }
-
-            e820_raw[e820_raw_nr].addr = 
-                ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
-            e820_raw[e820_raw_nr].size = 
-                ((u64)map->length_high << 32) | (u64)map->length_low;
-            e820_raw[e820_raw_nr].type = map->type;
-            e820_raw_nr++;
-
-            bytes += map->size + 4;
-        }
-    }
-    else if ( bootsym(lowmem_kb) )
-    {
-        memmap_type = "Xen-e801";
-        e820_raw[0].addr = 0;
-        e820_raw[0].size = bootsym(lowmem_kb) << 10;
-        e820_raw[0].type = E820_RAM;
-        e820_raw[1].addr = 0x100000;
-        e820_raw[1].size = bootsym(highmem_kb) << 10;
-        e820_raw[1].type = E820_RAM;
-        e820_raw_nr = 2;
-    }
-    else if ( mbi->flags & MBI_MEMLIMITS )
-    {
-        memmap_type = "Multiboot-e801";
-        e820_raw[0].addr = 0;
-        e820_raw[0].size = mbi->mem_lower << 10;
-        e820_raw[0].type = E820_RAM;
-        e820_raw[1].addr = 0x100000;
-        e820_raw[1].size = mbi->mem_upper << 10;
-        e820_raw[1].type = E820_RAM;
-        e820_raw_nr = 2;
-    }
-    else
-        panic("Bootloader provided no memory information.");
 
     /* Sanitise the raw E820 map to produce a final clean version. */
-    max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+    max_page = raw_max_page = init_e820(xbi->mmap_type, xbi->e820map, &xbi->e820map_nr);
 
     /* Create a temporary copy of the E820 map. */
     memcpy(&boot_e820, &e820, sizeof(e820));
@@ -769,8 +636,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     set_kexec_crash_area_size((u64)nr_pages << PAGE_SHIFT);
     kexec_reserve_area(&boot_e820);
 
-    initial_images = mod;
-    nr_initial_images = mbi->mods_count;
+    nr_initial_images = xbi->mods_nr;
+    initial_images = xbi->mods;
 
     /*
      * Iterate backwards over all superpage-aligned RAM regions.
@@ -785,16 +652,15 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * we can relocate the dom0 kernel and other multiboot modules. Also, on
      * x86/64, we relocate Xen to higher memory.
      */
-    for ( i = 0; !efi_enabled && i < mbi->mods_count; i++ )
+    for ( i = 0; !efi_enabled && i < xbi->mods_nr; i++ )
     {
-        if ( mod[i].mod_start & (PAGE_SIZE - 1) )
+        if ( xbi->mods[i].start & (PAGE_SIZE - 1) )
             panic("Bootloader didn't honor module alignment request.");
-        mod[i].mod_end -= mod[i].mod_start;
-        mod[i].mod_start >>= PAGE_SHIFT;
-        mod[i].reserved = 0;
+        xbi->mods[i].end -= xbi->mods[i].start;
+        xbi->mods[i].start >>= PAGE_SHIFT;
     }
 
-    modules_headroom = bzimage_headroom(bootstrap_map(mod), mod->mod_end);
+    modules_headroom = bzimage_headroom(bootstrap_map(xbi->mods), xbi->mods->end);
     bootstrap_map(NULL);
 
 #ifndef highmem_start
@@ -835,7 +701,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         {
             /* Don't overlap with modules. */
             end = consider_modules(s, e, reloc_size + mask,
-                                   mod, mbi->mods_count, -1);
+                                   xbi->mods, xbi->mods_nr, -1);
             end &= ~mask;
         }
         else
@@ -923,36 +789,36 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         }
 
         /* Is the region suitable for relocating the multiboot modules? */
-        for ( j = mbi->mods_count - 1; j >= 0; j-- )
+        for ( j = xbi->mods_nr - 1; j >= 0; j-- )
         {
             unsigned long headroom = j ? 0 : modules_headroom;
-            unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end);
+            unsigned long size = PAGE_ALIGN(headroom + xbi->mods[j].end);
 
-            if ( mod[j].reserved )
+            if ( xbi->mods[j].relocated )
                 continue;
 
             /* Don't overlap with other modules. */
-            end = consider_modules(s, e, size, mod, mbi->mods_count, j);
+            end = consider_modules(s, e, size, xbi->mods, xbi->mods_nr, j);
 
             if ( highmem_start && end > highmem_start )
                 continue;
 
             if ( s < end &&
                  (headroom ||
-                  ((end - size) >> PAGE_SHIFT) > mod[j].mod_start) )
+                  ((end - size) >> PAGE_SHIFT) > xbi->mods[j].start) )
             {
                 move_memory(end - size + headroom,
-                            (uint64_t)mod[j].mod_start << PAGE_SHIFT,
-                            mod[j].mod_end, 0);
-                mod[j].mod_start = (end - size) >> PAGE_SHIFT;
-                mod[j].mod_end += headroom;
-                mod[j].reserved = 1;
+                            (uint64_t)xbi->mods[j].start << PAGE_SHIFT,
+                            xbi->mods[j].end, 0);
+                xbi->mods[j].start = (end - size) >> PAGE_SHIFT;
+                xbi->mods[j].end += headroom;
+                xbi->mods[j].relocated = 1;
             }
         }
 
         /* Don't overlap with modules. */
         e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
-                             mod, mbi->mods_count, -1);
+                             xbi->mods, xbi->mods_nr, -1);
         if ( !kexec_crash_area.start && (s < e) )
         {
             e = (e - kexec_crash_area.size) & PAGE_MASK;
@@ -960,18 +826,18 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         }
     }
 
-    if ( modules_headroom && !mod->reserved )
+    if ( modules_headroom && !xbi->mods->relocated )
         panic("Not enough memory to relocate the dom0 kernel image.");
-    for ( i = 0; i < mbi->mods_count; ++i )
+    for ( i = 0; i < xbi->mods_nr; ++i )
     {
-        uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
+        uint64_t s = (uint64_t)xbi->mods[i].start << PAGE_SHIFT;
 
-        reserve_e820_ram(&boot_e820, s, s + PAGE_ALIGN(mod[i].mod_end));
+        reserve_e820_ram(&boot_e820, s, s + PAGE_ALIGN(xbi->mods[i].end));
     }
 
     if ( !xen_phys_start )
         panic("Not enough memory to relocate Xen.");
-    reserve_e820_ram(&boot_e820, efi_enabled ? mbi->mem_upper : __pa(&_start),
+    reserve_e820_ram(&boot_e820, efi_enabled ? xbi->mem_upper : __pa(&_start),
                      __pa(&_end));
 
     /* Late kexec reservation (dynamic start address). */
@@ -1017,10 +883,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                     ASSERT(j);
                 }
                 map_e = boot_e820.map[j].addr + boot_e820.map[j].size;
-                for ( j = 0; j < mbi->mods_count; ++j )
+                for ( j = 0; j < xbi->mods_nr; ++j )
                 {
-                    uint64_t end = pfn_to_paddr(mod[j].mod_start) +
-                                   mod[j].mod_end;
+                    uint64_t end = pfn_to_paddr(xbi->mods[j].start) +
+                                   xbi->mods[j].end;
 
                     if ( map_e < end )
                         map_e = end;
@@ -1093,13 +959,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
         }
     }
 
-    for ( i = 0; i < mbi->mods_count; ++i )
+    for ( i = 0; i < xbi->mods_nr; ++i )
     {
-        set_pdx_range(mod[i].mod_start,
-                      mod[i].mod_start + PFN_UP(mod[i].mod_end));
-        map_pages_to_xen((unsigned long)mfn_to_virt(mod[i].mod_start),
-                         mod[i].mod_start,
-                         PFN_UP(mod[i].mod_end), PAGE_HYPERVISOR);
+        set_pdx_range(xbi->mods[i].start,
+                      xbi->mods[i].start + PFN_UP(xbi->mods[i].end));
+        map_pages_to_xen((unsigned long)mfn_to_virt(xbi->mods[i].start),
+                         xbi->mods[i].start,
+                         PFN_UP(xbi->mods[i].end), PAGE_HYPERVISOR);
     }
 
     if ( kexec_crash_area.size )
@@ -1253,13 +1119,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
 
     init_IRQ();
 
-    module_map = xmalloc_array(unsigned long, BITS_TO_LONGS(mbi->mods_count));
-    bitmap_fill(module_map, mbi->mods_count);
+    module_map = xmalloc_array(unsigned long, BITS_TO_LONGS(xbi->mods_nr));
+    bitmap_fill(module_map, xbi->mods_nr);
     __clear_bit(0, module_map); /* Dom0 kernel is always first */
 
-    xsm_multiboot_init(module_map, mbi, bootstrap_map);
+    xsm_multiboot_init(module_map, xbi, bootstrap_map);
 
-    microcode_grab_module(module_map, mbi, bootstrap_map);
+    microcode_grab_module(module_map, xbi, bootstrap_map);
 
     timer_init();
 
@@ -1364,12 +1230,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     dom0->target = NULL;
 
     /* Grab the DOM0 command line. */
-    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
+    cmdline = (char *)(xbi->mods[0].cmdline ? __va(xbi->mods[0].cmdline) : NULL);
     if ( (cmdline != NULL) || (kextra != NULL) )
     {
         static char __initdata dom0_cmdline[MAX_GUEST_CMDLINE];
 
-        cmdline = cmdline_cook(cmdline, loader);
+        cmdline = cmdline_cook(cmdline, xbi->boot_loader_name);
         safe_strcpy(dom0_cmdline, cmdline);
 
         if ( kextra != NULL )
@@ -1396,8 +1262,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( xen_cpuidle )
         xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
 
-    initrdidx = find_first_bit(module_map, mbi->mods_count);
-    if ( bitmap_weight(module_map, mbi->mods_count) > 1 )
+    initrdidx = find_first_bit(module_map, xbi->mods_nr);
+    if ( bitmap_weight(module_map, xbi->mods_nr) > 1 )
         printk(XENLOG_WARNING
                "Multiple initrd candidates, picking module #%u\n",
                initrdidx);
@@ -1414,9 +1280,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
      * We're going to setup domain0 using the module(s) that we stashed safely
      * above our heap. The second module, if present, is an initrd ramdisk.
      */
-    if ( construct_dom0(dom0, mod, modules_headroom,
-                        (initrdidx > 0) && (initrdidx < mbi->mods_count)
-                        ? mod + initrdidx : NULL,
+    if ( construct_dom0(dom0, xbi->mods, modules_headroom,
+                        (initrdidx > 0) && (initrdidx < xbi->mods_nr)
+                        ? xbi->mods + initrdidx : NULL,
                         bootstrap_map, cmdline) != 0)
         panic("Could not set up DOM0 guest OS");
 
diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
index 3994f4d..2123eb3 100644
--- a/xen/arch/x86/x86_64/asm-offsets.c
+++ b/xen/arch/x86/x86_64/asm-offsets.c
@@ -12,7 +12,7 @@
 #include <compat/xen.h>
 #include <asm/fixmap.h>
 #include <asm/hardirq.h>
-#include <xen/multiboot.h>
+#include <asm/mbd.h>
 
 #define DEFINE(_sym, _val)                                                 \
     asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
@@ -163,6 +163,5 @@ void __dummy__(void)
     OFFSET(CPUINFO_features, struct cpuinfo_x86, x86_capability);
     BLANK();
 
-    OFFSET(MB_flags, multiboot_info_t, flags);
-    OFFSET(MB_cmdline, multiboot_info_t, cmdline);
+    OFFSET(MBD_cmdline, mbd_t, cmdline);
 }
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
index 93c983c..f034e1a 100644
--- a/xen/drivers/acpi/osl.c
+++ b/xen/drivers/acpi/osl.c
@@ -39,6 +39,7 @@
 #include <xen/domain_page.h>
 #include <xen/efi.h>
 #include <xen/vmap.h>
+#include <asm/xbi.h>
 
 #define _COMPONENT		ACPI_OS_SERVICES
 ACPI_MODULE_NAME("osl")
@@ -67,10 +68,10 @@ void __init acpi_os_vprintf(const char *fmt, va_list args)
 acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
 	if (efi_enabled) {
-		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
-			return efi.acpi20;
-		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
-			return efi.acpi;
+		if (xbi->acpi20 != EFI_INVALID_TABLE_ADDR)
+			return xbi->acpi20;
+		else if (xbi->acpi != EFI_INVALID_TABLE_ADDR)
+			return xbi->acpi;
 		else {
 			printk(KERN_ERR PREFIX
 			       "System description tables not found\n");
diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c
index 575db62..8941ac3 100644
--- a/xen/drivers/video/vesa.c
+++ b/xen/drivers/video/vesa.c
@@ -12,10 +12,11 @@
 #include <xen/vga.h>
 #include <asm/io.h>
 #include <asm/page.h>
+#include <asm/xbi.h>
 #include "font.h"
 #include "lfb.h"
 
-#define vlfb_info    vga_console_info.u.vesa_lfb
+#define vlfb_info    (xbi->vga_console_info.u.vesa_lfb)
 
 static void lfb_flush(void);
 
@@ -43,7 +44,7 @@ void __init vesa_early_init(void)
 {
     unsigned int vram_vmode;
 
-    vga_compat = !(vga_console_info.u.vesa_lfb.gbl_caps & 2);
+    vga_compat = !(xbi->vga_console_info.u.vesa_lfb.gbl_caps & 2);
 
     if ( (vlfb_info.bits_per_pixel < 8) || (vlfb_info.bits_per_pixel > 32) )
         return;
diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
index 40e5963..feb9b31 100644
--- a/xen/drivers/video/vga.c
+++ b/xen/drivers/video/vga.c
@@ -11,9 +11,7 @@
 #include <xen/vga.h>
 #include <xen/pci.h>
 #include <asm/io.h>
-
-/* Filled in by arch boot code. */
-struct xen_vga_console_info vga_console_info;
+#include <asm/xbi.h>
 
 static int vgacon_keep;
 static unsigned int xpos, ypos;
@@ -75,15 +73,15 @@ void __init video_init(void)
             vgacon_keep = 1;
     }
 
-    switch ( vga_console_info.video_type )
+    switch ( xbi->vga_console_info.video_type )
     {
     case XEN_VGATYPE_TEXT_MODE_3:
         if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) ||
              ((video = ioremap(0xB8000, 0x8000)) == NULL) )
             return;
         outw(0x200a, 0x3d4); /* disable cursor */
-        columns = vga_console_info.u.text_mode_3.columns;
-        lines   = vga_console_info.u.text_mode_3.rows;
+        columns = xbi->vga_console_info.u.text_mode_3.columns;
+        lines   = xbi->vga_console_info.u.text_mode_3.rows;
         memset(video, 0, columns * lines * 2);
         video_puts = vga_text_puts;
         break;
@@ -92,7 +90,7 @@ void __init video_init(void)
         vesa_early_init();
         break;
     default:
-        memset(&vga_console_info, 0, sizeof(vga_console_info));
+        memset(&xbi->vga_console_info, 0, sizeof(xbi->vga_console_info));
         break;
     }
 }
@@ -163,7 +161,7 @@ void __init video_endboot(void)
             }
     }
 
-    switch ( vga_console_info.video_type )
+    switch ( xbi->vga_console_info.video_type )
     {
     case XEN_VGATYPE_TEXT_MODE_3:
         if ( !vgacon_keep )
@@ -206,6 +204,6 @@ static void vga_text_puts(const char *s)
 
 int __init fill_console_start_info(struct dom0_vga_console_info *ci)
 {
-    memcpy(ci, &vga_console_info, sizeof(*ci));
+    memcpy(ci, &xbi->vga_console_info, sizeof(*ci));
     return 1;
 }
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index 210ff57..ae68322 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -119,8 +119,6 @@ extern unsigned int trampoline_xen_phys_start;
 extern unsigned char trampoline_cpu_started;
 extern char wakeup_start[];
 extern unsigned int video_mode, video_flags;
-extern unsigned short boot_edid_caps;
-extern unsigned char boot_edid_info[128];
 #endif
 
 #define asmlinkage
diff --git a/xen/include/asm-x86/e820.h b/xen/include/asm-x86/e820.h
index 08b413d..5d3683a 100644
--- a/xen/include/asm-x86/e820.h
+++ b/xen/include/asm-x86/e820.h
@@ -33,12 +33,4 @@ extern int e820_add_range(
 extern unsigned long init_e820(const char *, struct e820entry *, int *);
 extern struct e820map e820;
 
-/* These symbols live in the boot trampoline. */
-extern struct e820entry e820map[];
-extern int e820nr;
-extern unsigned int lowmem_kb, highmem_kb;
-
-#define e820_raw bootsym(e820map)
-#define e820_raw_nr bootsym(e820nr)
-
 #endif /*__E820_HEADER*/
diff --git a/xen/include/asm-x86/edd.h b/xen/include/asm-x86/edd.h
index afaa237..e8361a5 100644
--- a/xen/include/asm-x86/edd.h
+++ b/xen/include/asm-x86/edd.h
@@ -143,12 +143,6 @@ struct __packed mbr_signature {
     u32 signature;
 };
 
-/* These all reside in the boot trampoline. Access via bootsym(). */
-extern struct mbr_signature boot_mbr_signature[];
-extern u8 boot_mbr_signature_nr;
-extern struct edd_info boot_edd_info[];
-extern u8 boot_edd_info_nr;
-
 #endif /* __ASSEMBLY__ */
 
 /* Maximum number of EDD information structures at boot_edd_info. */
diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
index 8f8c6f3..88e9124 100644
--- a/xen/include/asm-x86/setup.h
+++ b/xen/include/asm-x86/setup.h
@@ -1,7 +1,7 @@
 #ifndef __X86_SETUP_H_
 #define __X86_SETUP_H_
 
-#include <xen/multiboot.h>
+#include <asm/xbi.h>
 
 extern unsigned long xenheap_initial_phys_start;
 
@@ -27,9 +27,9 @@ void vesa_mtrr_init(void);
 
 int construct_dom0(
     struct domain *d,
-    const module_t *kernel, unsigned long kernel_headroom,
-    module_t *initrd,
-    void *(*bootstrap_map)(const module_t *),
+    const boot_module_t *kernel, unsigned long kernel_headroom,
+    boot_module_t *initrd,
+    void *(*bootstrap_map)(const boot_module_t *),
     char *cmdline);
 
 unsigned long initial_images_nrpages(void);
@@ -38,7 +38,7 @@ void discard_initial_images(void);
 int xen_in_range(unsigned long mfn);
 
 void microcode_grab_module(
-    unsigned long *, const multiboot_info_t *, void *(*)(const module_t *));
+    unsigned long *, const xbi_t *, void *(*)(const boot_module_t *));
 
 extern uint8_t kbd_shift_flags;
 
diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
index 8a2b788..64d2dea 100644
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -9,16 +9,6 @@ extern const bool_t efi_enabled;
 
 #define EFI_INVALID_TABLE_ADDR (~0UL)
 
-/* Add fields here only if they need to be referenced from non-EFI code. */
-struct efi {
-    unsigned long mps;          /* MPS table */
-    unsigned long acpi;         /* ACPI table (IA64 ext 0.71) */
-    unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
-    unsigned long smbios;       /* SM BIOS table */
-};
-
-extern struct efi efi;
-
 #ifndef __ASSEMBLY__
 
 union xenpf_efi_info;
diff --git a/xen/include/xen/vga.h b/xen/include/xen/vga.h
index f72b63d..3d5c331 100644
--- a/xen/include/xen/vga.h
+++ b/xen/include/xen/vga.h
@@ -11,8 +11,4 @@
 
 #include <xen/video.h>
 
-#ifdef CONFIG_VGA
-extern struct xen_vga_console_info vga_console_info;
-#endif
-
 #endif /* _XEN_VGA_H */
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index a85045d..87f3729 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -16,7 +16,7 @@
 #define __XSM_H__
 
 #include <xen/sched.h>
-#include <xen/multiboot.h>
+#include <asm/xbi.h>
 
 typedef void xsm_op_t;
 DEFINE_XEN_GUEST_HANDLE(xsm_op_t);
@@ -659,11 +659,11 @@ static inline int xsm_ioport_mapping (xsm_default_t def, struct domain *d, uint3
 
 #ifdef CONFIG_MULTIBOOT
 extern int xsm_multiboot_init(unsigned long *module_map,
-                              const multiboot_info_t *mbi,
-                              void *(*bootstrap_map)(const module_t *));
+                              const xbi_t *xbi,
+                              void *(*bootstrap_map)(const boot_module_t *));
 extern int xsm_multiboot_policy_init(unsigned long *module_map,
-                                     const multiboot_info_t *mbi,
-                                     void *(*bootstrap_map)(const module_t *));
+                                     const xbi_t *xbi,
+                                     void *(*bootstrap_map)(const boot_module_t *));
 #endif
 
 #ifdef HAS_DEVICE_TREE
@@ -683,8 +683,8 @@ extern void xsm_fixup_ops(struct xsm_operations *ops);
 
 #ifdef CONFIG_MULTIBOOT
 static inline int xsm_multiboot_init (unsigned long *module_map,
-                                      const multiboot_info_t *mbi,
-                                      void *(*bootstrap_map)(const module_t *))
+                                      const xbi_t *xbi,
+                                      void *(*bootstrap_map)(const boot_module_t *))
 {
     return 0;
 }
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index 0ac6d03..85d4d33 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -60,8 +60,8 @@ static int __init xsm_core_init(void)
 
 #ifdef CONFIG_MULTIBOOT
 int __init xsm_multiboot_init(unsigned long *module_map,
-                              const multiboot_info_t *mbi,
-                              void *(*bootstrap_map)(const module_t *))
+                              const xbi_t *xbi,
+                              void *(*bootstrap_map)(const boot_module_t *))
 {
     int ret = 0;
 
@@ -69,7 +69,7 @@ int __init xsm_multiboot_init(unsigned long *module_map,
 
     if ( XSM_MAGIC )
     {
-        ret = xsm_multiboot_policy_init(module_map, mbi, bootstrap_map);
+        ret = xsm_multiboot_policy_init(module_map, xbi, bootstrap_map);
         if ( ret )
         {
             bootstrap_map(NULL);
diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
index 6e0bb78..5700eac 100644
--- a/xen/xsm/xsm_policy.c
+++ b/xen/xsm/xsm_policy.c
@@ -19,9 +19,6 @@
  */
 
 #include <xsm/xsm.h>
-#ifdef CONFIG_MULTIBOOT
-#include <xen/multiboot.h>
-#endif
 #include <xen/bitops.h>
 #ifdef HAS_DEVICE_TREE
 # include <asm/setup.h>
@@ -33,11 +30,10 @@ u32 __initdata policy_size = 0;
 
 #ifdef CONFIG_MULTIBOOT
 int __init xsm_multiboot_policy_init(unsigned long *module_map,
-                                     const multiboot_info_t *mbi,
-                                     void *(*bootstrap_map)(const module_t *))
+                                     const xbi_t *xbi,
+                                     void *(*bootstrap_map)(const boot_module_t *))
 {
     int i;
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
     int rc = 0;
     u32 *_policy_start;
     unsigned long _policy_len;
@@ -46,13 +42,13 @@ int __init xsm_multiboot_policy_init(unsigned long *module_map,
      * Try all modules and see whichever could be the binary policy.
      * Adjust module_map for the module that is the binary policy.
      */
-    for ( i = mbi->mods_count-1; i >= 1; i-- )
+    for ( i = xbi->mods_nr - 1; i >= 1; i-- )
     {
         if ( !test_bit(i, module_map) )
             continue;
 
-        _policy_start = bootstrap_map(mod + i);
-        _policy_len   = mod[i].mod_end;
+        _policy_start = bootstrap_map(xbi->mods + i);
+        _policy_len   = xbi->mods[i].end;
 
         if ( (xsm_magic_t)(*_policy_start) == XSM_MAGIC )
         {
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
                   ` (3 preceding siblings ...)
  2014-08-08 23:04 ` [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-10 17:23   ` Andrew Cooper
  2014-08-11 10:33   ` Jan Beulich
  2014-08-08 23:04 ` [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file Daniel Kiper
  2014-08-08 23:04 ` [PATCH RFC 7/7] xen/x86: Add new line to the end of graphics mode error message Daniel Kiper
  6 siblings, 2 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Add multiboot2 protocol support. This way we are laying the foundation
for EFI + GRUB2 + Xen development.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/boot/head.S  |  112 ++++++++++++++++++++++++++++++++++++++++++++-
 xen/arch/x86/boot/reloc.c |  103 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 212 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index 79bce3c..f0ea6d0 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -1,5 +1,6 @@
 #include <xen/config.h>
 #include <xen/multiboot.h>
+#include <xen/multiboot2.h>
 #include <public/xen.h>
 #include <asm/asm_defns.h>
 #include <asm/desc.h>
@@ -33,6 +34,68 @@ ENTRY(start)
         /* Checksum: must be the negated sum of the first two fields. */
         .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
 
+/*** MULTIBOOT2 HEADER ****/
+/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
+        .align  MULTIBOOT2_HEADER_ALIGN
+
+multiboot2_header:
+        /* Magic number indicating a Multiboot2 header. */
+        .long   MULTIBOOT2_HEADER_MAGIC
+        /* Architecture: i386. */
+        .long   MULTIBOOT2_ARCHITECTURE_I386
+        /* Multiboot2 header length. */
+        .long   multiboot2_header_end - multiboot2_header
+        /* Multiboot2 header checksum. */
+        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
+                        (multiboot2_header_end - multiboot2_header))
+
+        /* Multiboot2 tags... */
+multiboot2_info_req:
+        /* Multiboot2 information request tag. */
+        .short  MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST
+        .short  MULTIBOOT2_HEADER_TAG_REQUIRED
+        .long   multiboot2_info_req_end - multiboot2_info_req
+        .long   MULTIBOOT2_TAG_TYPE_MMAP
+multiboot2_info_req_end:
+
+        /*
+         * Align Xen image and modules at page boundry.
+         *
+         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
+         * to avoid bug related to Multiboot2 information request tag in earlier
+         * versions of GRUB2.
+         *
+         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
+         * WITH EARLIER GRUB2 VERSIONS!
+         */
+        .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END
+        .short   MULTIBOOT2_HEADER_TAG_MODULE_ALIGN
+        .short   MULTIBOOT2_HEADER_TAG_REQUIRED
+        .long    8 /* Tag size. */
+
+        /* Console flags tag. */
+        .align  MULTIBOOT2_TAG_ALIGN
+        .short  MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS
+        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
+        .long   12 /* Tag size. */
+        .long   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
+
+        /* Framebuffer tag. */
+        .align  MULTIBOOT2_TAG_ALIGN
+        .short  MULTIBOOT2_HEADER_TAG_FRAMEBUFFER
+        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
+        .long   20 /* Tag size. */
+        .long   0 /* Number of the columns - no preference. */
+        .long   0 /* Number of the lines - no preference. */
+        .long   0 /* Number of bits per pixel - no preference. */
+
+        /* Multiboot2 header end tag. */
+        .align  MULTIBOOT2_TAG_ALIGN
+        .short  MULTIBOOT2_HEADER_TAG_END
+        .short  0
+        .long   8 /* Tag size. */
+multiboot2_header_end:
+
         .section .init.rodata, "a", @progbits
         .align 4
 
@@ -81,10 +144,55 @@ __start:
         mov     %ecx,%es
         mov     %ecx,%ss
 
+        /* Set mem_lower to 0 */
+        xor     %edx,%edx
+
         /* Check for Multiboot bootloader */
-        cmp     $0x2BADB002,%eax
-        jne     not_multiboot
+        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
+        je      1f
+
+        /* Check for Multiboot2 bootloader */
+        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+        je      2f
+
+        jmp     not_multiboot
+
+1:
+        /* Get mem_lower from Multiboot information */
+        testb   $MBI_MEMLIMITS,(%ebx)
+        jz      0f                  /* not available? BDA value will be fine */
 
+        mov     4(%ebx),%edx
+        shl     $10-4,%edx
+        jmp     0f
+
+2:
+        /* Get Multiboot2 information address */
+        mov     %ebx,%ecx
+        add     $8,%ecx
+
+3:
+        /* Get mem_lower from Multiboot2 information */
+        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
+        jne     4f
+
+        mov     8(%ecx),%edx
+        shl     $10-4,%edx
+        jmp     5f
+
+4:
+        /* Is it the end of Multiboot2 information? */
+        cmpl    $MULTIBOOT2_TAG_TYPE_END,(%ecx)
+        je      0f
+
+5:
+        /* Go to next Multiboot2 information tag */
+        add     4(%ecx),%ecx
+        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
+        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
+        jmp     3b
+
+0:
         /* Set up trampoline segment 64k below EBDA */
         movzwl  0x40e,%ecx          /* EBDA segment */
         cmp     $0xa000,%ecx        /* sanity check (high) */
diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
index 29f4887..eaf3226 100644
--- a/xen/arch/x86/boot/reloc.c
+++ b/xen/arch/x86/boot/reloc.c
@@ -18,8 +18,12 @@ typedef unsigned long u32;
 typedef unsigned long long u64;
 
 #include "../../../include/xen/multiboot.h"
+#include "../../../include/xen/multiboot2.h"
 #include "../../../include/asm/mbd.h"
 
+#define ALIGN_UP(addr, align) \
+                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align - 1))
+
 /*
  * __HERE__ IS TRUE ENTRY POINT!!!
  *
@@ -144,6 +148,100 @@ static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
     return mbd;
 }
 
+static mbd_t *mb2_mbd(mbd_t *mbd, void *mbi)
+{
+    int i, mod_idx = 0;
+    memory_map_t *mmap_dst;
+    multiboot2_memory_map_t *mmap_src;
+    multiboot2_tag_t *tag;
+    u32 ptr;
+    boot_module_t *mbd_mods;
+
+    /* Skip Multiboot2 information fixed part. */
+    tag = mbi + sizeof(u32) * 2;
+
+    while ( 1 )
+    {
+        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
+            ++mbd->mods_nr;
+        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
+        {
+            mbd->mods = alloc_struct(mbd->mods_nr * sizeof(boot_module_t));
+            mbd_mods = (boot_module_t *)mbd->mods;
+            break;
+        }
+
+        /* Go to next Multiboot2 information tag. */
+        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
+    }
+
+    /* Skip Multiboot2 information fixed part. */
+    tag = mbi + sizeof(u32) * 2;
+
+    while ( 1 )
+    {
+        switch ( tag->type )
+        {
+        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
+            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
+            mbd->boot_loader_name = copy_string(ptr);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_CMDLINE:
+            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
+            mbd->cmdline = copy_string(ptr);
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
+            mbd->mem_lower = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_lower;
+            mbd->mem_upper = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_upper;
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MMAP:
+            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
+            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
+            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
+            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
+            mbd->mmap_size *= sizeof(memory_map_t);
+
+            mbd->mmap = alloc_struct(mbd->mmap_size);
+
+            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
+            mmap_dst = (memory_map_t *)mbd->mmap;
+
+            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)
+            {
+                mmap_dst[i].size = sizeof(memory_map_t);
+                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
+                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
+                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
+                mmap_dst[i].length_low = (u32)mmap_src[i].len;
+                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
+                mmap_dst[i].type = mmap_src[i].type;
+            }
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_MODULE:
+            mbd_mods[mod_idx].start = (u32)((multiboot2_tag_module_t *)tag)->mod_start;
+            mbd_mods[mod_idx].end = (u32)((multiboot2_tag_module_t *)tag)->mod_end;
+            ptr = (u32)((multiboot2_tag_module_t *)tag)->cmdline;
+            mbd_mods[mod_idx].cmdline = copy_string(ptr);
+            mbd_mods[mod_idx].relocated = 0;
+            ++mod_idx;
+            break;
+
+        case MULTIBOOT2_TAG_TYPE_END:
+            return mbd;
+
+        default:
+            break;
+        }
+
+        /* Go to next Multiboot2 information tag. */
+        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
+    }
+}
+
 /*
  * __THIS__ IS NOT ENTRY POINT!!!
  * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
@@ -158,5 +256,8 @@ mbd_t *__reloc(void *mbi, u32 mb_magic)
     mbd = (mbd_t *)alloc_struct(sizeof(mbd_t));
     zero_struct((u32)mbd, sizeof(mbd_t));
 
-    return mb_mbd(mbd, mbi);
+    if ( mb_magic == MULTIBOOT_BOOTLOADER_MAGIC )
+        return mb_mbd(mbd, mbi);
+    else
+        return mb2_mbd(mbd, mbi);
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
                   ` (4 preceding siblings ...)
  2014-08-08 23:04 ` [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  2014-08-11 10:35   ` Jan Beulich
  2014-08-08 23:04 ` [PATCH RFC 7/7] xen/x86: Add new line to the end of graphics mode error message Daniel Kiper
  6 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

xen/include/xen/vga.h just include xen/include/xen/video.h.
So, remove it because it is redundant file.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/efi/boot.c   |    2 +-
 xen/arch/x86/setup.c      |    2 +-
 xen/drivers/video/vesa.c  |    2 +-
 xen/drivers/video/vga.c   |    2 +-
 xen/include/asm-x86/xbi.h |    2 +-
 xen/include/xen/vga.h     |   14 --------------
 6 files changed, 5 insertions(+), 19 deletions(-)
 delete mode 100644 xen/include/xen/vga.h

diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index fea5598..4ad9352 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -16,7 +16,7 @@
 #endif
 #include <xen/string.h>
 #include <xen/stringify.h>
-#include <xen/vga.h>
+#include <xen/video.h>
 #include <asm/e820.h>
 #include <asm/edd.h>
 #define __ASSEMBLY__ /* avoid pulling in ACPI stuff (conflicts with EFI) */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index b3bf26a..75fbb3a 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -20,7 +20,7 @@
 #include <xen/keyhandler.h>
 #include <xen/numa.h>
 #include <xen/rcupdate.h>
-#include <xen/vga.h>
+#include <xen/video.h>
 #include <xen/dmi.h>
 #include <xen/pfn.h>
 #include <xen/nodemask.h>
diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c
index 8941ac3..e1fe662 100644
--- a/xen/drivers/video/vesa.c
+++ b/xen/drivers/video/vesa.c
@@ -9,7 +9,7 @@
 #include <xen/lib.h>
 #include <xen/xmalloc.h>
 #include <xen/kernel.h>
-#include <xen/vga.h>
+#include <xen/video.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/xbi.h>
diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
index feb9b31..5089fea 100644
--- a/xen/drivers/video/vga.c
+++ b/xen/drivers/video/vga.c
@@ -8,7 +8,7 @@
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
-#include <xen/vga.h>
+#include <xen/video.h>
 #include <xen/pci.h>
 #include <asm/io.h>
 #include <asm/xbi.h>
diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
index ca9e615..a86bb55 100644
--- a/xen/include/asm-x86/xbi.h
+++ b/xen/include/asm-x86/xbi.h
@@ -19,7 +19,7 @@
 #define __XBI_H__
 
 #include <xen/types.h>
-#include <xen/vga.h>
+#include <xen/video.h>
 
 #include <asm/e820.h>
 #include <asm/edd.h>
diff --git a/xen/include/xen/vga.h b/xen/include/xen/vga.h
deleted file mode 100644
index 3d5c331..0000000
--- a/xen/include/xen/vga.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *  vga.h
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License.  See the file COPYING in the main directory of this archive
- *  for more details.
- */
-
-#ifndef _XEN_VGA_H
-#define _XEN_VGA_H
-
-#include <xen/video.h>
-
-#endif /* _XEN_VGA_H */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH RFC 7/7] xen/x86: Add new line to the end of graphics mode error message
  2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
                   ` (5 preceding siblings ...)
  2014-08-08 23:04 ` [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file Daniel Kiper
@ 2014-08-08 23:04 ` Daniel Kiper
  6 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-08 23:04 UTC (permalink / raw)
  To: xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Error message related to graphics mode does not have new line.
So, let's fix it.

Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 xen/arch/x86/efi/boot.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
index 4ad9352..085fcd7 100644
--- a/xen/arch/x86/efi/boot.c
+++ b/xen/arch/x86/efi/boot.c
@@ -1362,7 +1362,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
                     break;
                 /* fall through */
             default:
-                PrintErr(L"Current graphics mode is unsupported!");
+                PrintErr(L"Current graphics mode is unsupported!\r\n");
                 status = EFI_UNSUPPORTED;
                 break;
             }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-08 23:04 ` [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper
@ 2014-08-09  0:07   ` Roy Franz
  2014-08-10 16:22     ` Daniel Kiper
  2014-08-10 17:05   ` Andrew Cooper
  1 sibling, 1 reply; 40+ messages in thread
From: Roy Franz @ 2014-08-09  0:07 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, Ian Campbell, Stefano Stabellini, ross.philipson, ning.sun,
	Jan Beulich, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, Fu Wei

On Fri, Aug 8, 2014 at 4:04 PM, Daniel Kiper <daniel.kiper@oracle.com> wrote:
> We have all constants and structures in place. So, finally break multiboot (v1)
> protocol dependency. It means that most of Xen code (excluding preloader)
> could be bootloader agnostic and does not need almost any knowledge about
> boot protocol. Additionally, we are able to pass all boot data to __start_xen()
> in one bucket without any side channels. I do not mention that we are also
> able to easily identify boot data in Xen code.
>
> Here is boot data flow for legacy BIOS platform:
>
>   BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
>                                                         /
>                      -----------------<-----------------
>                      \
>                       \
>                        ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
>                       /
>              BIOS ->-/
>
>   * multiboot2 is not implemented yet. Look for it in next patch.
>
> Here is boot data flow for EFI platform:
>
>   EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI
>
> WARNING: ARM build could be broken by this patch. We need to agree XBI
> integration into ARM. Personally I think that it is worth storing all
> data from any bootloader and preloader in XBI on any architecture. This
> give a chance to share more code between architectures. However, every
> architecture should define its own XBI (in relevant include/asm directory).
> Despite that it looks that some parts of it could be common, e.g.  modules
> data, command line arguments, boot loader name, EFI data, etc., even if types
> would not be the same. So, as it was stated above a lot of code could be
> shared among architectures.

From looking at this patch, it only conflicts slightly with the arm64 EFI work
I have been doing.  Most of the changes are to areas of efi/boot.c that I don't
touch.  From a practical point of view it should be relatively easy
for me to base
my patch series on yours or vice versa.
GRUB uses device tree to describe modules passed to XEN, so it's
not clear to me what the advantage of translating a device tree description
of modules into an ARM specific XBI structure would have.

Roy

>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/arch/x86/Makefile             |    1 +
>  xen/arch/x86/boot/cmdline.S       |    9 +-
>  xen/arch/x86/boot/head.S          |   31 ++--
>  xen/arch/x86/boot/reloc.c         |  153 ++++++++++++-----
>  xen/arch/x86/boot/x86_64.S        |   10 +-
>  xen/arch/x86/dmi_scan.c           |    7 +-
>  xen/arch/x86/domain_build.c       |   24 +--
>  xen/arch/x86/efi/boot.c           |  212 +++++++++++------------
>  xen/arch/x86/efi/efi.h            |    3 -
>  xen/arch/x86/efi/runtime.c        |   52 ++++--
>  xen/arch/x86/init_xbi.c           |  254 +++++++++++++++++++++++++++
>  xen/arch/x86/microcode.c          |   39 ++---
>  xen/arch/x86/mpparse.c            |    9 +-
>  xen/arch/x86/platform_hypercall.c |   19 +--
>  xen/arch/x86/setup.c              |  340 +++++++++++--------------------------
>  xen/arch/x86/x86_64/asm-offsets.c |    5 +-
>  xen/drivers/acpi/osl.c            |    9 +-
>  xen/drivers/video/vesa.c          |    5 +-
>  xen/drivers/video/vga.c           |   16 +-
>  xen/include/asm-x86/config.h      |    2 -
>  xen/include/asm-x86/e820.h        |    8 -
>  xen/include/asm-x86/edd.h         |    6 -
>  xen/include/asm-x86/setup.h       |   10 +-
>  xen/include/xen/efi.h             |   10 --
>  xen/include/xen/vga.h             |    4 -
>  xen/include/xsm/xsm.h             |   14 +-
>  xen/xsm/xsm_core.c                |    6 +-
>  xen/xsm/xsm_policy.c              |   14 +-
>  28 files changed, 723 insertions(+), 549 deletions(-)
>  create mode 100644 xen/arch/x86/init_xbi.c
>
> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> index c1e244d..bb2264a 100644
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -42,6 +42,7 @@ obj-y += numa.o
>  obj-y += pci.o
>  obj-y += percpu.o
>  obj-y += physdev.o
> +obj-y += init_xbi.o
>  obj-y += setup.o
>  obj-y += shutdown.o
>  obj-y += smp.o
> diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
> index 00687eb..7316011 100644
> --- a/xen/arch/x86/boot/cmdline.S
> +++ b/xen/arch/x86/boot/cmdline.S
> @@ -152,17 +152,14 @@ cmdline_parse_early:
>          pusha
>
>          /* Bail if there is no command line to parse. */
> -        mov     sym_phys(multiboot_ptr),%ebx
> -        mov     MB_flags(%ebx),%eax
> -        test    $4,%al
> -        jz      .Lcmdline_exit
> -        mov     MB_cmdline(%ebx),%eax
> +        mov     sym_phys(mbd_ptr),%ebx
> +        mov     MBD_cmdline(%ebx),%eax
>          test    %eax,%eax
>          jz      .Lcmdline_exit
>
>          /* Check for 'no-real-mode' command-line option. */
>          pushl   $sym_phys(.Lno_rm_opt)
> -        pushl   MB_cmdline(%ebx)
> +        pushl   MBD_cmdline(%ebx)
>          call    .Lfind_option
>          test    %eax,%eax
>          setnz   %al
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 10ecf51..79bce3c 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -86,14 +86,14 @@ __start:
>          jne     not_multiboot
>
>          /* Set up trampoline segment 64k below EBDA */
> -        movzwl  0x40e,%eax          /* EBDA segment */
> -        cmp     $0xa000,%eax        /* sanity check (high) */
> +        movzwl  0x40e,%ecx          /* EBDA segment */
> +        cmp     $0xa000,%ecx        /* sanity check (high) */
>          jae     0f
> -        cmp     $0x4000,%eax        /* sanity check (low) */
> +        cmp     $0x4000,%ecx        /* sanity check (low) */
>          jae     1f
>  0:
> -        movzwl  0x413,%eax          /* use base memory size on failure */
> -        shl     $10-4,%eax
> +        movzwl  0x413,%ecx          /* use base memory size on failure */
> +        shl     $10-4,%ecx
>  1:
>          /*
>           * Compare the value in the BDA with the information from the
> @@ -105,22 +105,23 @@ __start:
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
>          jb      2f                  /* if so, do not use it */
>          shl     $10-4,%edx
> -        cmp     %eax,%edx           /* compare with BDA value */
> -        cmovb   %edx,%eax           /* and use the smaller */
> +        cmp     %ecx,%edx           /* compare with BDA value */
> +        cmovb   %edx,%ecx           /* and use the smaller */
>
>  2:      /* Reserve 64kb for the trampoline */
> -        sub     $0x1000,%eax
> +        sub     $0x1000,%ecx
>
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
> -        xor     %al, %al
> -        shl     $4, %eax
> -        mov     %eax,sym_phys(trampoline_phys)
> +        xor     %cl, %cl
> +        shl     $4, %ecx
> +        mov     %ecx,sym_phys(trampoline_phys)
>
> -        /* Save the Multiboot info struct (after relocation) for later use. */
> +        /* Save the Multiboot data (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
> -        push    %ebx
> -        call    reloc
> -        mov     %eax,sym_phys(multiboot_ptr)
> +        push    %eax                /* Multiboot magic */
> +        push    %ebx                /* Multiboot information address */
> +        call    reloc               /* %ecx contains trampoline address */
> +        mov     %eax,sym_phys(mbd_ptr)
>
>          /* Initialize BSS (no nasty surprises!) */
>          mov     $sym_phys(__bss_start),%edi
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index fa0fb6b..29f4887 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -1,40 +1,56 @@
> -/******************************************************************************
> +/*
>   * reloc.c
> - *
> + *
>   * 32-bit flat memory-map routines for relocating Multiboot structures
>   * and modules. This is most easily done early with paging disabled.
> - *
> + *
>   * Copyright (c) 2009, Citrix Systems, Inc.
> - *
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
>   * Authors:
>   *    Keir Fraser <keir@xen.org>
> + *    Daniel Kiper
>   */
>
> -/* entered with %eax = BOOT_TRAMPOLINE */
> +typedef unsigned char u8;
> +typedef unsigned short u16;
> +typedef unsigned long u32;
> +typedef unsigned long long u64;
> +
> +#include "../../../include/xen/multiboot.h"
> +#include "../../../include/asm/mbd.h"
> +
> +/*
> + * __HERE__ IS TRUE ENTRY POINT!!!
> + *
> + * It is entered from xen/arch/x86/boot/head.S with:
> + *   - %eax = MULTIBOOT_MAGIC,
> + *   - %ebx = MULTIBOOT_INFORMATION_ADDRESS,
> + *   - %ecx = BOOT_TRAMPOLINE.
> + */
>  asm (
>      "    .text                         \n"
>      "    .globl _start                 \n"
>      "_start:                           \n"
>      "    call 1f                       \n"
>      "1:  pop  %ebx                     \n"
> -    "    mov  %eax,alloc-1b(%ebx)      \n"
> -    "    jmp  reloc                    \n"
> +    "    mov  %ecx,alloc-1b(%ebx)      \n"
> +    "    jmp  __reloc                  \n"
>      );
>
> -/* This is our data.  Because the code must be relocatable, no BSS is
> - * allowed.  All data is accessed PC-relative with inline assembly.
> +/*
> + * This is our data. Because the code must be relocatable, no BSS is
> + * allowed. All data is accessed PC-relative with inline assembly.
>   */
>  asm (
>      "alloc:                            \n"
>      "    .long 0                       \n"
>      );
>
> -typedef unsigned int u32;
> -#include "../../../include/xen/multiboot.h"
> -
> -static void *reloc_mbi_struct(void *old, unsigned int bytes)
> +static u32 alloc_struct(u32 bytes)
>  {
> -    void *new;
> +    u32 s;
> +
>      asm(
>      "    call 1f                      \n"
>      "1:  pop  %%edx                   \n"
> @@ -42,58 +58,105 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
>      "    sub  %1,%0                   \n"
>      "    and  $~15,%0                 \n"
>      "    mov  %0,alloc-1b(%%edx)      \n"
> -    "    mov  %0,%%edi                \n"
> +       : "=&r" (s) : "r" (bytes) : "edx");
> +
> +    return s;
> +}
> +
> +static void zero_struct(u32 s, u32 bytes)
> +{
> +    asm volatile(
> +    "    cld                          \n"
> +    "    xor  %%eax,%%eax             \n"
> +    "    rep  stosb                   \n"
> +       : "+D" (s), "+c" (bytes) : : "eax");
> +}
> +
> +static u32 copy_struct(u32 src, u32 bytes)
> +{
> +    u32 dst;
> +
> +    dst = alloc_struct(bytes);
> +
> +    asm volatile(
> +    "    cld                          \n"
> +    "    mov  %2,%%edi                \n"
>      "    rep  movsb                   \n"
> -       : "=&r" (new), "+c" (bytes), "+S" (old)
> -       : : "edx", "edi");
> -    return new;
> +       : "+S" (src), "+c" (bytes) : "r" (dst) : "edi");
> +
> +    return dst;
>  }
>
> -static char *reloc_mbi_string(char *old)
> +static u32 copy_string(u32 src)
>  {
>      char *p;
> -    for ( p = old; *p != '\0'; p++ )
> +
> +    if ( src == 0 )
> +        return 0;
> +
> +    for ( p = (char *)src; *p != '\0'; p++ )
>          continue;
> -    return reloc_mbi_struct(old, p - old + 1);
> +
> +    return copy_struct(src, p - (char *)src + 1);
>  }
>
> -multiboot_info_t *reloc(multiboot_info_t *mbi_old)
> +static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
>  {
> -    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
>      int i;
> +    module_t *mbi_mods;
> +    boot_module_t *mbd_mods;
> +
> +    if ( mbi->flags & MBI_LOADERNAME )
> +        mbd->boot_loader_name = copy_string(mbi->boot_loader_name);
>
>      if ( mbi->flags & MBI_CMDLINE )
> -        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
> +        mbd->cmdline = copy_string(mbi->cmdline);
> +
> +    if ( mbi->flags & MBI_MEMLIMITS )
> +    {
> +        mbd->mem_lower = mbi->mem_lower;
> +        mbd->mem_upper = mbi->mem_upper;
> +    }
> +
> +    if ( mbi->flags & MBI_MEMMAP )
> +    {
> +        mbd->mmap_size = mbi->mmap_length;
> +        mbd->mmap = copy_struct(mbi->mmap_addr, mbi->mmap_length);
> +    }
>
>      if ( mbi->flags & MBI_MODULES )
>      {
> -        module_t *mods = reloc_mbi_struct(
> -            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
> +        mbd->mods_nr = mbi->mods_count;
> +        mbd->mods = alloc_struct(mbi->mods_count * sizeof(boot_module_t));
>
> -        mbi->mods_addr = (u32)mods;
> +        mbi_mods = (module_t *)mbi->mods_addr;
> +        mbd_mods = (boot_module_t *)mbd->mods;
>
>          for ( i = 0; i < mbi->mods_count; i++ )
>          {
> -            if ( mods[i].string )
> -                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
> +            mbd_mods[i].start = mbi_mods[i].mod_start;
> +            mbd_mods[i].end = mbi_mods[i].mod_end;
> +            mbd_mods[i].cmdline = copy_string(mbi_mods[i].string);
> +            mbd_mods[i].relocated = 0;
>          }
>      }
>
> -    if ( mbi->flags & MBI_MEMMAP )
> -        mbi->mmap_addr = (u32)reloc_mbi_struct(
> -            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
> +    return mbd;
> +}
>
> -    if ( mbi->flags & MBI_LOADERNAME )
> -        mbi->boot_loader_name = (u32)reloc_mbi_string(
> -            (char *)mbi->boot_loader_name);
> -
> -    /* Mask features we don't understand or don't relocate. */
> -    mbi->flags &= (MBI_MEMLIMITS |
> -                   MBI_BOOTDEV |
> -                   MBI_CMDLINE |
> -                   MBI_MODULES |
> -                   MBI_MEMMAP |
> -                   MBI_LOADERNAME);
> -
> -    return mbi;
> +/*
> + * __THIS__ IS NOT ENTRY POINT!!!
> + * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
> + *
> + * It could be a static but then compiler complains:
> + * error: ‘__reloc’ defined but not used.
> + */
> +mbd_t *__reloc(void *mbi, u32 mb_magic)
> +{
> +    mbd_t *mbd;
> +
> +    mbd = (mbd_t *)alloc_struct(sizeof(mbd_t));
> +    zero_struct((u32)mbd, sizeof(mbd_t));
> +
> +    return mb_mbd(mbd, mbi);
>  }
> diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
> index bfbafd2..ec39d38 100644
> --- a/xen/arch/x86/boot/x86_64.S
> +++ b/xen/arch/x86/boot/x86_64.S
> @@ -29,8 +29,12 @@
>          test    %ebx,%ebx
>          jnz     start_secondary
>
> -        /* Pass off the Multiboot info structure to C land. */
> -        mov     multiboot_ptr(%rip),%edi
> +        /* Init Xen Boot Info. */
> +        mov     mbd_ptr(%rip),%edi
> +        call    __init_xbi
> +
> +        /* Pass off the Xen Boot Info to C land. */
> +        movq    %rax,%rdi
>          call    __start_xen
>          ud2     /* Force a panic (invalid opcode). */
>
> @@ -38,7 +42,7 @@
>
>          .data
>          .align 8
> -multiboot_ptr:
> +mbd_ptr:
>          .long   0
>
>          .word   0
> diff --git a/xen/arch/x86/dmi_scan.c b/xen/arch/x86/dmi_scan.c
> index 500133a..cd89360 100644
> --- a/xen/arch/x86/dmi_scan.c
> +++ b/xen/arch/x86/dmi_scan.c
> @@ -12,6 +12,7 @@
>  #include <xen/efi.h>
>  #include <xen/pci.h>
>  #include <xen/pci_regs.h>
> +#include <asm/xbi.h>
>
>  #define bt_ioremap(b,l)  ((void *)__acpi_map_table(b,l))
>  #define bt_iounmap(b,l)  ((void)0)
> @@ -215,10 +216,10 @@ static int __init dmi_efi_iterate(void (*decode)(struct dmi_header *))
>         const struct smbios_eps __iomem *p;
>         int ret = -1;
>
> -       if (efi.smbios == EFI_INVALID_TABLE_ADDR)
> +       if (xbi->smbios == EFI_INVALID_TABLE_ADDR)
>                 return -1;
>
> -       p = bt_ioremap(efi.smbios, sizeof(eps));
> +       p = bt_ioremap(xbi->smbios, sizeof(eps));
>         if (!p)
>                 return -1;
>         memcpy_fromio(&eps, p, sizeof(eps));
> @@ -227,7 +228,7 @@ static int __init dmi_efi_iterate(void (*decode)(struct dmi_header *))
>         if (memcmp(eps.anchor, "_SM_", 4))
>                 return -1;
>
> -       p = bt_ioremap(efi.smbios, eps.length);
> +       p = bt_ioremap(xbi->smbios, eps.length);
>         if (!p)
>                 return -1;
>         if (dmi_checksum(p, eps.length) &&
> diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
> index d4473c1..e35260b 100644
> --- a/xen/arch/x86/domain_build.c
> +++ b/xen/arch/x86/domain_build.c
> @@ -751,9 +751,9 @@ static __init void setup_pv_physmap(struct domain *d, unsigned long pgtbl_pfn,
>
>  int __init construct_dom0(
>      struct domain *d,
> -    const module_t *image, unsigned long image_headroom,
> -    module_t *initrd,
> -    void *(*bootstrap_map)(const module_t *),
> +    const boot_module_t *image, unsigned long image_headroom,
> +    boot_module_t *initrd,
> +    void *(*bootstrap_map)(const boot_module_t *),
>      char *cmdline)
>  {
>      int i, cpu, rc, compatible, compat32, order, machine;
> @@ -770,9 +770,9 @@ int __init construct_dom0(
>      struct vcpu *v = d->vcpu[0];
>      unsigned long long value;
>      char *image_base = bootstrap_map(image);
> -    unsigned long image_len = image->mod_end;
> +    unsigned long image_len = image->end;
>      char *image_start = image_base + image_headroom;
> -    unsigned long initrd_len = initrd ? initrd->mod_end : 0;
> +    unsigned long initrd_len = initrd ? initrd->end : 0;
>      l4_pgentry_t *l4tab = NULL, *l4start = NULL;
>      l3_pgentry_t *l3tab = NULL, *l3start = NULL;
>      l2_pgentry_t *l2tab = NULL, *l2start = NULL;
> @@ -987,7 +987,7 @@ int __init construct_dom0(
>          initrd_pfn = vinitrd_start ?
>                       (vinitrd_start - v_start) >> PAGE_SHIFT :
>                       d->tot_pages;
> -        initrd_mfn = mfn = initrd->mod_start;
> +        initrd_mfn = mfn = initrd->start;
>          count = PFN_UP(initrd_len);
>          if ( d->arch.physaddr_bitsize &&
>               ((mfn + count - 1) >> (d->arch.physaddr_bitsize - PAGE_SHIFT)) )
> @@ -1002,12 +1002,12 @@ int __init construct_dom0(
>                      free_domheap_pages(page, order);
>                      page += 1UL << order;
>                  }
> -            memcpy(page_to_virt(page), mfn_to_virt(initrd->mod_start),
> +            memcpy(page_to_virt(page), mfn_to_virt(initrd->start),
>                     initrd_len);
> -            mpt_alloc = (paddr_t)initrd->mod_start << PAGE_SHIFT;
> +            mpt_alloc = (paddr_t)initrd->start << PAGE_SHIFT;
>              init_domheap_pages(mpt_alloc,
>                                 mpt_alloc + PAGE_ALIGN(initrd_len));
> -            initrd->mod_start = initrd_mfn = page_to_mfn(page);
> +            initrd->start = initrd_mfn = page_to_mfn(page);
>          }
>          else
>          {
> @@ -1015,7 +1015,7 @@ int __init construct_dom0(
>                  if ( assign_pages(d, mfn_to_page(mfn++), 0, 0) )
>                      BUG();
>          }
> -        initrd->mod_end = 0;
> +        initrd->end = 0;
>      }
>
>      printk("PHYSICAL MEMORY ARRANGEMENT:\n"
> @@ -1026,7 +1026,7 @@ int __init construct_dom0(
>                 nr_pages - d->tot_pages);
>      if ( initrd )
>      {
> -        mpt_alloc = (paddr_t)initrd->mod_start << PAGE_SHIFT;
> +        mpt_alloc = (paddr_t)initrd->start << PAGE_SHIFT;
>          printk("\n Init. ramdisk: %"PRIpaddr"->%"PRIpaddr,
>                 mpt_alloc, mpt_alloc + initrd_len);
>      }
> @@ -1281,7 +1281,7 @@ int __init construct_dom0(
>          if ( pfn >= initrd_pfn )
>          {
>              if ( pfn < initrd_pfn + PFN_UP(initrd_len) )
> -                mfn = initrd->mod_start + (pfn - initrd_pfn);
> +                mfn = initrd->start + (pfn - initrd_pfn);
>              else
>                  mfn -= PFN_UP(initrd_len);
>          }
> diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c
> index 2b515f2..fea5598 100644
> --- a/xen/arch/x86/efi/boot.c
> +++ b/xen/arch/x86/efi/boot.c
> @@ -9,7 +9,6 @@
>  #include <xen/keyhandler.h>
>  #include <xen/lib.h>
>  #include <xen/mm.h>
> -#include <xen/multiboot.h>
>  #include <xen/pci_regs.h>
>  #include <xen/pfn.h>
>  #if EFI_PAGE_SIZE != PAGE_SIZE
> @@ -25,6 +24,7 @@
>  #undef __ASSEMBLY__
>  #include <asm/msr.h>
>  #include <asm/processor.h>
> +#include <asm/xbi.h>
>
>  /* Using SetVirtualAddressMap() is incompatible with kexec: */
>  #undef USE_SET_VIRTUAL_ADDRESS_MAP
> @@ -72,13 +72,12 @@ static struct file __initdata ramdisk;
>  static struct file __initdata ucode;
>  static struct file __initdata xsm;
>
> -static multiboot_info_t __initdata mbi = {
> -    .flags = MBI_MODULES | MBI_LOADERNAME
> -};
> -static module_t __initdata mb_modules[3];
> -
>  static CHAR16 __initdata newline[] = L"\r\n";
>
> +extern unsigned short boot_edid_caps;
> +
> +extern xbi_t __read_mostly xbi_efi;
> +
>  #define PrintStr(s) StdOut->OutputString(StdOut, s)
>  #define PrintErr(s) StdErr->OutputString(StdErr, s)
>
> @@ -255,14 +254,14 @@ static void __init PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode)
>      blexit(mesg);
>  }
>
> -static void __init place_string(u32 *addr, const char *s)
> +static void __init place_string_char(char **addr, const char *s)
>  {
>      static char *__initdata alloc = start;
>
>      if ( s && *s )
>      {
>          size_t len1 = strlen(s) + 1;
> -        const char *old = (char *)(long)*addr;
> +        const char *old = *addr;
>          size_t len2 = *addr ? strlen(old) + 1 : 0;
>
>          alloc -= len1 + len2;
> @@ -278,7 +277,16 @@ static void __init place_string(u32 *addr, const char *s)
>              memcpy(alloc + len1, old, len2);
>          }
>      }
> -    *addr = (long)alloc;
> +    *addr = alloc;
> +}
> +
> +static void __init place_string_u32(u32 *addr, const char *s)
> +{
> +    char *s_new = (char *)(long)*addr;
> +
> +    place_string_char(&s_new, s);
> +
> +    *addr = (long)s_new;
>  }
>
>  static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
> @@ -311,7 +319,7 @@ static unsigned int __init get_argv(unsigned int argc, CHAR16 **argv,
>                  union string rest = { .w = cmdline };
>
>                  --argv;
> -                place_string(&mbi.cmdline, w2s(&rest));
> +                place_string_char(&xbi_efi.cmdline, w2s(&rest));
>                  break;
>              }
>              else
> @@ -480,9 +488,9 @@ static bool_t __init read_file(EFI_FILE_HANDLE dir_handle, CHAR16 *name,
>              PrintStr(L"-");
>              DisplayUint(file->addr + size, 2 * sizeof(file->addr));
>              PrintStr(newline);
> -            mb_modules[mbi.mods_count].mod_start = file->addr >> PAGE_SHIFT;
> -            mb_modules[mbi.mods_count].mod_end = size;
> -            ++mbi.mods_count;
> +            xbi_efi.mods[xbi_efi.mods_nr].start = file->addr >> PAGE_SHIFT;
> +            xbi_efi.mods[xbi_efi.mods_nr].end = size;
> +            ++xbi_efi.mods_nr;
>          }
>
>          file->size = size;
> @@ -568,7 +576,7 @@ static void __init split_value(char *s)
>  {
>      while ( *s && isspace(*s) )
>          ++s;
> -    place_string(&mb_modules[mbi.mods_count].string, s);
> +    place_string_u32(&xbi_efi.mods[xbi_efi.mods_nr].cmdline, s);
>      while ( *s && !isspace(*s) )
>          ++s;
>      *s = 0;
> @@ -884,10 +892,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
>                             &cols, &rows) == EFI_SUCCESS )
>      {
> -        vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
> -        vga_console_info.u.text_mode_3.columns = cols;
> -        vga_console_info.u.text_mode_3.rows = rows;
> -        vga_console_info.u.text_mode_3.font_height = 16;
> +        xbi_efi.vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
> +        xbi_efi.vga_console_info.u.text_mode_3.columns = cols;
> +        xbi_efi.vga_console_info.u.text_mode_3.rows = rows;
> +        xbi_efi.vga_console_info.u.text_mode_3.font_height = 16;
>      }
>
>      size = 0;
> @@ -984,7 +992,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>          name.s = get_value(&cfg, "global", "ucode");
>      if ( name.s )
>      {
> -        microcode_set_module(mbi.mods_count);
> +        microcode_set_module(xbi_efi.mods_nr);
>          split_value(name.s);
>          read_file(dir_handle, s2w(&name), &ucode);
>          efi_bs->FreePool(name.w);
> @@ -1000,7 +1008,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>
>      name.s = get_value(&cfg, section.s, "options");
>      if ( name.s )
> -        place_string(&mbi.cmdline, name.s);
> +        place_string_char(&xbi_efi.cmdline, name.s);
>      /* Insert image name last, as it gets prefixed to the other options. */
>      if ( argc )
>      {
> @@ -1009,7 +1017,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      }
>      else
>          name.s = "xen";
> -    place_string(&mbi.cmdline, name.s);
> +    place_string_char(&xbi_efi.cmdline, name.s);
>
>      cols = rows = depth = 0;
>      if ( !base_video )
> @@ -1075,16 +1083,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>          }
>      }
>
> -    if ( mbi.cmdline )
> -        mbi.flags |= MBI_CMDLINE;
> -    /*
> -     * These must not be initialized statically, since the value must
> -     * not get relocated when processing base relocations below.
> -     */
> -    mbi.boot_loader_name = (long)"EFI";
> -    mbi.mods_addr = (long)mb_modules;
> +    xbi_efi.efi_system_table = SystemTable;
> +    xbi_efi.edid_caps = boot_edid_caps;
>
> -    place_string(&mbi.mem_upper, NULL);
> +    place_string_u32(&xbi_efi.mem_upper, NULL);
>
>      /* Collect EDD info. */
>      BUILD_BUG_ON(offsetof(struct edd_info, edd_device_params) != EDDEXTSIZE);
> @@ -1102,7 +1104,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      {
>          EFI_BLOCK_IO *bio;
>          EFI_DEV_PATH_PTR devp;
> -        struct edd_info *info = boot_edd_info + boot_edd_info_nr;
> +        struct edd_info *info = xbi_efi.edd_info + xbi_efi.edd_info_nr;
>          struct edd_device_params *params = &info->edd_device_params;
>          enum { root, acpi, pci, ctrlr } state = root;
>
> @@ -1111,16 +1113,16 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>               bio->Media->RemovableMedia ||
>               bio->Media->LogicalPartition )
>              continue;
> -        if ( boot_edd_info_nr < EDD_INFO_MAX )
> +        if ( xbi_efi.edd_info_nr < EDD_INFO_MAX )
>          {
> -            info->device = 0x80 + boot_edd_info_nr; /* fake */
> +            info->device = 0x80 + xbi_efi.edd_info_nr; /* fake */
>              info->version = 0x11;
>              params->length = offsetof(struct edd_device_params, dpte_ptr);
>              params->number_of_sectors = bio->Media->LastBlock + 1;
>              params->bytes_per_sector = bio->Media->BlockSize;
>              params->dpte_ptr = ~0;
>          }
> -        ++boot_edd_info_nr;
> +        ++xbi_efi.edd_info_nr;
>          status = efi_bs->HandleProtocol(handles[i], &devp_guid,
>                                          (void **)&devp);
>          if ( EFI_ERROR(status) )
> @@ -1133,7 +1135,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>                  const u8 *p;
>
>              case ACPI_DEVICE_PATH:
> -                if ( state != root || boot_edd_info_nr > EDD_INFO_MAX )
> +                if ( state != root || xbi_efi.edd_info_nr > EDD_INFO_MAX )
>                      break;
>                  switch ( DevicePathSubType(devp.DevPath) )
>                  {
> @@ -1152,7 +1154,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              case HARDWARE_DEVICE_PATH:
>                  if ( state != acpi ||
>                       DevicePathSubType(devp.DevPath) != HW_PCI_DP ||
> -                     boot_edd_info_nr > EDD_INFO_MAX )
> +                     xbi_efi.edd_info_nr > EDD_INFO_MAX )
>                      break;
>                  state = pci;
>                  edd_put_string(params->host_bus_type, "PCI");
> @@ -1160,7 +1162,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>                  params->interface_path.pci.function = devp.Pci->Function;
>                  break;
>              case MESSAGING_DEVICE_PATH:
> -                if ( state != pci || boot_edd_info_nr > EDD_INFO_MAX )
> +                if ( state != pci || xbi_efi.edd_info_nr > EDD_INFO_MAX )
>                      break;
>                  state = ctrlr;
>                  switch ( DevicePathSubType(devp.DevPath) )
> @@ -1209,15 +1211,15 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              case MEDIA_DEVICE_PATH:
>                  if ( DevicePathSubType(devp.DevPath) == MEDIA_HARDDRIVE_DP &&
>                       devp.HardDrive->MBRType == MBR_TYPE_PCAT &&
> -                     boot_mbr_signature_nr < EDD_MBR_SIG_MAX )
> +                     xbi_efi.mbr_signature_nr < EDD_MBR_SIG_MAX )
>                  {
> -                    struct mbr_signature *sig = boot_mbr_signature +
> -                                                boot_mbr_signature_nr;
> +                    struct mbr_signature *sig = xbi_efi.mbr_signature +
> +                                                xbi_efi.mbr_signature_nr;
>
> -                    sig->device = 0x80 + boot_edd_info_nr; /* fake */
> +                    sig->device = 0x80 + xbi_efi.edd_info_nr; /* fake */
>                      memcpy(&sig->signature, devp.HardDrive->Signature,
>                             sizeof(sig->signature));
> -                    ++boot_mbr_signature_nr;
> +                    ++xbi_efi.mbr_signature_nr;
>                  }
>                  break;
>              }
> @@ -1225,8 +1227,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>      }
>      if ( handles )
>          efi_bs->FreePool(handles);
> -    if ( boot_edd_info_nr > EDD_INFO_MAX )
> -        boot_edd_info_nr = EDD_INFO_MAX;
> +    if ( xbi_efi.edd_info_nr > EDD_INFO_MAX )
> +        xbi_efi.edd_info_nr = EDD_INFO_MAX;
>
>      /* XXX Collect EDID info. */
>
> @@ -1245,17 +1247,17 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>          static EFI_GUID __initdata smbios_guid = SMBIOS_TABLE_GUID;
>
>          if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) )
> -              efi.acpi20 = (long)efi_ct[i].VendorTable;
> +              xbi_efi.acpi20 = (long)efi_ct[i].VendorTable;
>          if ( match_guid(&acpi_guid, &efi_ct[i].VendorGuid) )
> -              efi.acpi = (long)efi_ct[i].VendorTable;
> +              xbi_efi.acpi = (long)efi_ct[i].VendorTable;
>          if ( match_guid(&mps_guid, &efi_ct[i].VendorGuid) )
> -              efi.mps = (long)efi_ct[i].VendorTable;
> +              xbi_efi.mps = (long)efi_ct[i].VendorTable;
>          if ( match_guid(&smbios_guid, &efi_ct[i].VendorGuid) )
> -              efi.smbios = (long)efi_ct[i].VendorTable;
> +              xbi_efi.smbios = (long)efi_ct[i].VendorTable;
>      }
>
> -    if (efi.smbios != EFI_INVALID_TABLE_ADDR)
> -        dmi_efi_get_table((void *)(long)efi.smbios);
> +    if (xbi_efi.smbios != EFI_INVALID_TABLE_ADDR)
> +        dmi_efi_get_table((void *)(long)xbi_efi.smbios);
>
>      /* Collect PCI ROM contents. */
>      setup_efi_pci();
> @@ -1322,40 +1324,40 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              switch ( mode_info->PixelFormat )
>              {
>              case PixelRedGreenBlueReserved8BitPerColor:
> -                vga_console_info.u.vesa_lfb.red_pos = 0;
> -                vga_console_info.u.vesa_lfb.red_size = 8;
> -                vga_console_info.u.vesa_lfb.green_pos = 8;
> -                vga_console_info.u.vesa_lfb.green_size = 8;
> -                vga_console_info.u.vesa_lfb.blue_pos = 16;
> -                vga_console_info.u.vesa_lfb.blue_size = 8;
> -                vga_console_info.u.vesa_lfb.rsvd_pos = 24;
> -                vga_console_info.u.vesa_lfb.rsvd_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.red_pos = 0;
> +                xbi_efi.vga_console_info.u.vesa_lfb.red_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.green_pos = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.green_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.blue_pos = 16;
> +                xbi_efi.vga_console_info.u.vesa_lfb.blue_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos = 24;
> +                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size = 8;
>                  bpp = 32;
>                  break;
>              case PixelBlueGreenRedReserved8BitPerColor:
> -                vga_console_info.u.vesa_lfb.red_pos = 16;
> -                vga_console_info.u.vesa_lfb.red_size = 8;
> -                vga_console_info.u.vesa_lfb.green_pos = 8;
> -                vga_console_info.u.vesa_lfb.green_size = 8;
> -                vga_console_info.u.vesa_lfb.blue_pos = 0;
> -                vga_console_info.u.vesa_lfb.blue_size = 8;
> -                vga_console_info.u.vesa_lfb.rsvd_pos = 24;
> -                vga_console_info.u.vesa_lfb.rsvd_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.red_pos = 16;
> +                xbi_efi.vga_console_info.u.vesa_lfb.red_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.green_pos = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.green_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.blue_pos = 0;
> +                xbi_efi.vga_console_info.u.vesa_lfb.blue_size = 8;
> +                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos = 24;
> +                xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size = 8;
>                  bpp = 32;
>                  break;
>              case PixelBitMask:
>                  bpp = set_color(mode_info->PixelInformation.RedMask, bpp,
> -                                &vga_console_info.u.vesa_lfb.red_pos,
> -                                &vga_console_info.u.vesa_lfb.red_size);
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.red_pos,
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.red_size);
>                  bpp = set_color(mode_info->PixelInformation.GreenMask, bpp,
> -                                &vga_console_info.u.vesa_lfb.green_pos,
> -                                &vga_console_info.u.vesa_lfb.green_size);
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.green_pos,
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.green_size);
>                  bpp = set_color(mode_info->PixelInformation.BlueMask, bpp,
> -                                &vga_console_info.u.vesa_lfb.blue_pos,
> -                                &vga_console_info.u.vesa_lfb.blue_size);
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.blue_pos,
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.blue_size);
>                  bpp = set_color(mode_info->PixelInformation.ReservedMask, bpp,
> -                                &vga_console_info.u.vesa_lfb.rsvd_pos,
> -                                &vga_console_info.u.vesa_lfb.rsvd_size);
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.rsvd_pos,
> +                                &xbi_efi.vga_console_info.u.vesa_lfb.rsvd_size);
>                  if ( bpp > 0 )
>                      break;
>                  /* fall through */
> @@ -1366,37 +1368,37 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              }
>          if ( !EFI_ERROR(status) )
>          {
> -            vga_console_info.video_type = XEN_VGATYPE_EFI_LFB;
> -            vga_console_info.u.vesa_lfb.gbl_caps = 2; /* possibly non-VGA */
> -            vga_console_info.u.vesa_lfb.width =
> +            xbi_efi.vga_console_info.video_type = XEN_VGATYPE_EFI_LFB;
> +            xbi_efi.vga_console_info.u.vesa_lfb.gbl_caps = 2; /* possibly non-VGA */
> +            xbi_efi.vga_console_info.u.vesa_lfb.width =
>                  mode_info->HorizontalResolution;
> -            vga_console_info.u.vesa_lfb.height = mode_info->VerticalResolution;
> -            vga_console_info.u.vesa_lfb.bits_per_pixel = bpp;
> -            vga_console_info.u.vesa_lfb.bytes_per_line =
> +            xbi_efi.vga_console_info.u.vesa_lfb.height = mode_info->VerticalResolution;
> +            xbi_efi.vga_console_info.u.vesa_lfb.bits_per_pixel = bpp;
> +            xbi_efi.vga_console_info.u.vesa_lfb.bytes_per_line =
>                  (mode_info->PixelsPerScanLine * bpp + 7) >> 3;
> -            vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
> -            vga_console_info.u.vesa_lfb.lfb_size =
> +            xbi_efi.vga_console_info.u.vesa_lfb.lfb_base = gop->Mode->FrameBufferBase;
> +            xbi_efi.vga_console_info.u.vesa_lfb.lfb_size =
>                  (gop->Mode->FrameBufferSize + 0xffff) >> 16;
>          }
>      }
>
> -    efi_bs->GetMemoryMap(&efi_memmap_size, NULL, &map_key,
> -                         &efi_mdesc_size, &mdesc_ver);
> -    mbi.mem_upper -= efi_memmap_size;
> -    mbi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
> -    if ( mbi.mem_upper < xen_phys_start )
> -        blexit(L"Out of static memory");
> -    efi_memmap = (void *)(long)mbi.mem_upper;
> -    status = efi_bs->GetMemoryMap(&efi_memmap_size, efi_memmap, &map_key,
> -                                  &efi_mdesc_size, &mdesc_ver);
> +    efi_bs->GetMemoryMap(&xbi_efi.efi_mmap_size, NULL, &map_key,
> +                        &xbi_efi.efi_mmap_desc_size, &mdesc_ver);
> +    xbi_efi.mem_upper -= xbi_efi.efi_mmap_size;
> +    xbi_efi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
> +    if ( xbi_efi.mem_upper < xen_phys_start )
> +        blexit(L"Out of static memory\r\n");
> +    xbi_efi.efi_mmap = (void *)(long)xbi_efi.mem_upper;
> +    status = efi_bs->GetMemoryMap(&xbi_efi.efi_mmap_size, xbi_efi.efi_mmap, &map_key,
> +                                  &xbi_efi.efi_mmap_desc_size, &mdesc_ver);
>      if ( EFI_ERROR(status) )
>          PrintErrMesg(L"Cannot obtain memory map", status);
>
>      /* Populate E820 table and check trampoline area availability. */
> -    e = e820map - 1;
> -    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> +    e = xbi_efi.e820map - 1;
> +    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
>      {
> -        EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> +        EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
>          u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
>          u32 type;
>
> @@ -1427,10 +1429,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              type = E820_NVS;
>              break;
>          }
> -        if ( e820nr && type == e->type &&
> +        if ( xbi_efi.e820map_nr && type == e->type &&
>               desc->PhysicalStart == e->addr + e->size )
>              e->size += len;
> -        else if ( !len || e820nr >= E820MAX )
> +        else if ( !len || xbi_efi.e820map_nr >= E820MAX )
>              continue;
>          else
>          {
> @@ -1438,7 +1440,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>              e->addr = desc->PhysicalStart;
>              e->size = len;
>              e->type = type;
> -            ++e820nr;
> +            ++xbi_efi.e820map_nr;
>          }
>      }
>      if ( !trampoline_phys )
> @@ -1457,7 +1459,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>  #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
>      efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
>  #endif
> -    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
> +    xbi_efi.efi_mmap = (void *)xbi_efi.efi_mmap + DIRECTMAP_VIRT_START;
>      efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
>
>      relocate_image(__XEN_VIRT_START - xen_phys_start);
> @@ -1491,7 +1493,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
>                       [cs] "ir" (__HYPERVISOR_CS),
>                       [ds] "r" (__HYPERVISOR_DS),
>                       [stkoff] "i" (STACK_SIZE - sizeof(struct cpu_info)),
> -                     "D" (&mbi)
> +                     "D" (&xbi_efi)
>                     : "memory" );
>      for( ; ; ); /* not reached */
>  }
> @@ -1557,9 +1559,9 @@ void __init efi_init_memory(void)
>  #endif
>
>      printk(XENLOG_INFO "EFI memory map:\n");
> -    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> +    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
>      {
> -        EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> +        EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
>          u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
>          unsigned long smfn, emfn;
>          unsigned int prot = PAGE_HYPERVISOR;
> @@ -1634,8 +1636,8 @@ void __init efi_init_memory(void)
>      }
>
>  #ifdef USE_SET_VIRTUAL_ADDRESS_MAP
> -    efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size,
> -                                 mdesc_ver, efi_memmap);
> +    efi_rs->SetVirtualAddressMap(xbi_efi.efi_mmap_size, xbi_efi.efi_mmap_desc_size,
> +                                 mdesc_ver, xbi_efi.efi_mmap);
>  #else
>      /* Set up 1:1 page tables to do runtime calls in "physical" mode. */
>      efi_l4_pgtable = alloc_xen_pagetable();
> @@ -1645,9 +1647,9 @@ void __init efi_init_memory(void)
>      copy_mapping(0, max_page, ram_range_valid);
>
>      /* Insert non-RAM runtime mappings inside the direct map. */
> -    for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> +    for ( i = 0; i < xbi_efi.efi_mmap_size; i += xbi_efi.efi_mmap_desc_size )
>      {
> -        const EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> +        const EFI_MEMORY_DESCRIPTOR *desc = xbi_efi.efi_mmap + i;
>
>          if ( (desc->Attribute & EFI_MEMORY_RUNTIME) &&
>               desc->VirtualStart != INVALID_VIRTUAL_ADDRESS &&
> diff --git a/xen/arch/x86/efi/efi.h b/xen/arch/x86/efi/efi.h
> index a80d5f1..46099de 100644
> --- a/xen/arch/x86/efi/efi.h
> +++ b/xen/arch/x86/efi/efi.h
> @@ -25,9 +25,6 @@ extern const CHAR16 *efi_fw_vendor;
>
>  extern EFI_RUNTIME_SERVICES *efi_rs;
>
> -extern UINTN efi_memmap_size, efi_mdesc_size;
> -extern void *efi_memmap;
> -
>  extern l4_pgentry_t *efi_l4_pgtable;
>
>  extern const struct efi_pci_rom *efi_pci_roms;
> diff --git a/xen/arch/x86/efi/runtime.c b/xen/arch/x86/efi/runtime.c
> index 166852d..3ef4b5b 100644
> --- a/xen/arch/x86/efi/runtime.c
> +++ b/xen/arch/x86/efi/runtime.c
> @@ -5,6 +5,7 @@
>  #include <xen/irq.h>
>  #include <xen/time.h>
>  #include <asm/mc146818rtc.h>
> +#include <asm/xbi.h>
>
>  DEFINE_XEN_GUEST_HANDLE(CHAR16);
>
> @@ -26,25 +27,50 @@ const CHAR16 *__read_mostly efi_fw_vendor;
>  EFI_RUNTIME_SERVICES *__read_mostly efi_rs;
>  static DEFINE_SPINLOCK(efi_rs_lock);
>
> -UINTN __read_mostly efi_memmap_size;
> -UINTN __read_mostly efi_mdesc_size;
> -void *__read_mostly efi_memmap;
> -
>  UINT64 __read_mostly efi_boot_max_var_store_size;
>  UINT64 __read_mostly efi_boot_remain_var_store_size;
>  UINT64 __read_mostly efi_boot_max_var_size;
>
> -struct efi __read_mostly efi = {
> -       .acpi   = EFI_INVALID_TABLE_ADDR,
> -       .acpi20 = EFI_INVALID_TABLE_ADDR,
> -       .mps    = EFI_INVALID_TABLE_ADDR,
> -       .smbios = EFI_INVALID_TABLE_ADDR,
> -};
> -
>  l4_pgentry_t *__read_mostly efi_l4_pgtable;
>
>  const struct efi_pci_rom *__read_mostly efi_pci_roms;
>
> +extern struct e820entry e820map[];
> +extern struct edd_info boot_edd_info[];
> +extern struct mbr_signature boot_mbr_signature[];
> +
> +extern unsigned char boot_edid_info[128];
> +
> +static boot_module_t __read_mostly xbi_mods[3] = {};
> +
> +xbi_t __read_mostly xbi_efi = {
> +    .boot_loader_name = "EFI",
> +    .cmdline = NULL,
> +    .mmap_type = "EFI",
> +    .mem_upper = 0,
> +    .e820map_nr = 0,
> +    .e820map = e820map,
> +    .efi_mmap_size = 0,
> +    .efi_mmap_desc_size = 0,
> +    .efi_mmap = NULL,
> +    .mps = EFI_INVALID_TABLE_ADDR,
> +    .acpi = EFI_INVALID_TABLE_ADDR,
> +    .acpi20 = EFI_INVALID_TABLE_ADDR,
> +    .smbios = EFI_INVALID_TABLE_ADDR,
> +    .efi_system_table = NULL,
> +    .vga_console_info = {},
> +    .edid_caps = 0,
> +    .edid_info = boot_edid_info,
> +    .edd_info_nr = 0,
> +    .edd_info = boot_edd_info,
> +    .mbr_signature_nr = 0,
> +    .mbr_signature = boot_mbr_signature,
> +    .mods_nr = 0,
> +    .mods = xbi_mods,
> +    .warn_msg = NULL,
> +    .err_msg = NULL
> +};
> +
>  unsigned long efi_rs_enter(void)
>  {
>      static const u16 fcw = FCW_DEFAULT;
> @@ -173,9 +199,9 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info *info)
>          }
>          break;
>      case XEN_FW_EFI_MEM_INFO:
> -        for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> +        for ( i = 0; i < xbi->efi_mmap_size; i += xbi->efi_mmap_desc_size )
>          {
> -            EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> +            EFI_MEMORY_DESCRIPTOR *desc = xbi->efi_mmap + i;
>              u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
>
>              if ( info->mem.addr >= desc->PhysicalStart &&
> diff --git a/xen/arch/x86/init_xbi.c b/xen/arch/x86/init_xbi.c
> new file mode 100644
> index 0000000..aebb9cc
> --- /dev/null
> +++ b/xen/arch/x86/init_xbi.c
> @@ -0,0 +1,254 @@
> +/*
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/*
> + * Some ideas are taken (out) from xen/arch/x86/boot/reloc.c,
> + * xen/arch/x86/efi/boot.c and xen/arch/x86/setup.c.
> + */
> +
> +#include <xen/types.h>
> +#include <xen/cache.h>
> +#include <xen/efi.h>
> +#include <xen/init.h>
> +#include <xen/multiboot.h>
> +
> +#include <asm/e820.h>
> +#include <asm/mbd.h>
> +#include <asm/page.h>
> +#include <asm/xbi.h>
> +
> +struct boot_video_info {
> +    u8  orig_x;             /* 0x00 */
> +    u8  orig_y;             /* 0x01 */
> +    u8  orig_video_mode;    /* 0x02 */
> +    u8  orig_video_cols;    /* 0x03 */
> +    u8  orig_video_lines;   /* 0x04 */
> +    u8  orig_video_isVGA;   /* 0x05 */
> +    u16 orig_video_points;  /* 0x06 */
> +
> +    /* VESA graphic mode -- linear frame buffer */
> +    u32 capabilities;       /* 0x08 */
> +    u16 lfb_linelength;     /* 0x0c */
> +    u16 lfb_width;          /* 0x0e */
> +    u16 lfb_height;         /* 0x10 */
> +    u16 lfb_depth;          /* 0x12 */
> +    u32 lfb_base;           /* 0x14 */
> +    u32 lfb_size;           /* 0x18 */
> +    u8  red_size;           /* 0x1c */
> +    u8  red_pos;            /* 0x1d */
> +    u8  green_size;         /* 0x1e */
> +    u8  green_pos;          /* 0x1f */
> +    u8  blue_size;          /* 0x20 */
> +    u8  blue_pos;           /* 0x21 */
> +    u8  rsvd_size;          /* 0x22 */
> +    u8  rsvd_pos;           /* 0x23 */
> +    u16 vesapm_seg;         /* 0x24 */
> +    u16 vesapm_off;         /* 0x26 */
> +    u16 vesa_attrib;        /* 0x28 */
> +};
> +
> +/* These symbols live in the boot trampoline. Access via bootsym(). */
> +extern struct e820entry e820map[];
> +extern int e820nr;
> +extern unsigned int lowmem_kb, highmem_kb;
> +
> +extern struct boot_video_info boot_vid_info;
> +
> +extern unsigned short boot_edid_caps;
> +extern unsigned char boot_edid_info[128];
> +
> +extern struct edd_info boot_edd_info[];
> +extern u8 boot_edd_info_nr;
> +
> +extern struct mbr_signature boot_mbr_signature[];
> +extern u8 boot_mbr_signature_nr;
> +
> +static xbi_t __read_mostly xbi_mb = {
> +    .boot_loader_name = "UNKNOWN",
> +    .cmdline = NULL,
> +    .mmap_type = NULL,
> +    .mem_upper = 0,
> +    .e820map_nr = 0,
> +    .e820map = NULL,
> +    .efi_mmap_size = 0,
> +    .efi_mmap_desc_size = 0,
> +    .efi_mmap = NULL,
> +    .mps = EFI_INVALID_TABLE_ADDR,
> +    .acpi = EFI_INVALID_TABLE_ADDR,
> +    .acpi20 = EFI_INVALID_TABLE_ADDR,
> +    .smbios = EFI_INVALID_TABLE_ADDR,
> +    .efi_system_table = NULL,
> +    .vga_console_info = {},
> +    .edid_caps = 0,
> +    .edid_info = NULL,
> +    .edd_info_nr = 0,
> +    .edd_info = NULL,
> +    .mbr_signature_nr = 0,
> +    .mbr_signature = NULL,
> +    .mods_nr = 0,
> +    .mods = NULL,
> +    .warn_msg = NULL,
> +    .err_msg = NULL
> +};
> +
> +#define e820_raw bootsym(e820map)
> +#define e820_raw_nr bootsym(e820nr)
> +
> +static void __init init_mmap(xbi_t *xbi, mbd_t *mbd)
> +{
> +    int bytes = 0;
> +    memory_map_t *map;
> +
> +    if ( e820_raw_nr )
> +        xbi->mmap_type = "Xen-e820";
> +    else if ( mbd->mmap_size )
> +    {
> +        xbi->mmap_type = "Multiboot-e820";
> +
> +        while ( (bytes < mbd->mmap_size) && (e820_raw_nr < E820MAX) )
> +        {
> +            /*
> +             * This is a gross workaround for a BIOS bug. Some bootloaders do
> +             * not write e820 map entries into pre-zeroed memory. This is
> +             * okay if the BIOS fills in all fields of the map entry, but
> +             * some broken BIOSes do not bother to write the high word of
> +             * the length field if the length is smaller than 4GB. We
> +             * detect and fix this by flagging sections below 4GB that
> +             * appear to be larger than 4GB in size.
> +             */
> +            map = __va(mbd->mmap + bytes);
> +
> +            if ( !map->base_addr_high && map->length_high )
> +            {
> +                map->length_high = 0;
> +                xbi->warn_msg = "WARNING: Buggy e820 map detected and fixed "
> +                                "(truncated length fields).\n";
> +            }
> +
> +            e820_raw[e820_raw_nr].addr =
> +                ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
> +            e820_raw[e820_raw_nr].size =
> +                ((u64)map->length_high << 32) | (u64)map->length_low;
> +            e820_raw[e820_raw_nr].type = map->type;
> +            e820_raw_nr++;
> +
> +            bytes += map->size + 4;
> +        }
> +    }
> +    else if ( bootsym(lowmem_kb) )
> +    {
> +        xbi->mmap_type = "Xen-e801";
> +
> +        e820_raw[0].addr = 0;
> +        e820_raw[0].size = bootsym(lowmem_kb) << 10;
> +        e820_raw[0].type = E820_RAM;
> +        e820_raw[1].addr = 0x100000;
> +        e820_raw[1].size = bootsym(highmem_kb) << 10;
> +        e820_raw[1].type = E820_RAM;
> +        e820_raw_nr = 2;
> +    }
> +    else if ( mbd->mem_lower || mbd->mem_upper )
> +    {
> +        xbi->mmap_type = "Multiboot-e801";
> +
> +        e820_raw[0].addr = 0;
> +        e820_raw[0].size = mbd->mem_lower << 10;
> +        e820_raw[0].type = E820_RAM;
> +        e820_raw[1].addr = 0x100000;
> +        e820_raw[1].size = mbd->mem_upper << 10;
> +        e820_raw[1].type = E820_RAM;
> +        e820_raw_nr = 2;
> +    }
> +    else
> +    {
> +        xbi->err_msg = "Bootloader provided no memory information.\n";
> +        return;
> +    }
> +
> +    xbi->mem_upper = mbd->mem_upper;
> +
> +    xbi->e820map_nr = e820_raw_nr;
> +    xbi->e820map = e820_raw;
> +}
> +
> +static void __init init_video_info(xbi_t *xbi)
> +{
> +    struct boot_video_info *bvi = &bootsym(boot_vid_info);
> +
> +    if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
> +    {
> +        xbi->vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
> +        xbi->vga_console_info.u.text_mode_3.font_height = bvi->orig_video_points;
> +        xbi->vga_console_info.u.text_mode_3.cursor_x = bvi->orig_x;
> +        xbi->vga_console_info.u.text_mode_3.cursor_y = bvi->orig_y;
> +        xbi->vga_console_info.u.text_mode_3.rows = bvi->orig_video_lines;
> +        xbi->vga_console_info.u.text_mode_3.columns = bvi->orig_video_cols;
> +    }
> +    else if ( bvi->orig_video_isVGA == 0x23 )
> +    {
> +        xbi->vga_console_info.video_type = XEN_VGATYPE_VESA_LFB;
> +        xbi->vga_console_info.u.vesa_lfb.width = bvi->lfb_width;
> +        xbi->vga_console_info.u.vesa_lfb.height = bvi->lfb_height;
> +        xbi->vga_console_info.u.vesa_lfb.bytes_per_line = bvi->lfb_linelength;
> +        xbi->vga_console_info.u.vesa_lfb.bits_per_pixel = bvi->lfb_depth;
> +        xbi->vga_console_info.u.vesa_lfb.lfb_base = bvi->lfb_base;
> +        xbi->vga_console_info.u.vesa_lfb.lfb_size = bvi->lfb_size;
> +        xbi->vga_console_info.u.vesa_lfb.red_pos = bvi->red_pos;
> +        xbi->vga_console_info.u.vesa_lfb.red_size = bvi->red_size;
> +        xbi->vga_console_info.u.vesa_lfb.green_pos = bvi->green_pos;
> +        xbi->vga_console_info.u.vesa_lfb.green_size = bvi->green_size;
> +        xbi->vga_console_info.u.vesa_lfb.blue_pos = bvi->blue_pos;
> +        xbi->vga_console_info.u.vesa_lfb.blue_size = bvi->blue_size;
> +        xbi->vga_console_info.u.vesa_lfb.rsvd_pos = bvi->rsvd_pos;
> +        xbi->vga_console_info.u.vesa_lfb.rsvd_size = bvi->rsvd_size;
> +        xbi->vga_console_info.u.vesa_lfb.gbl_caps = bvi->capabilities;
> +        xbi->vga_console_info.u.vesa_lfb.mode_attrs = bvi->vesa_attrib;
> +    }
> +
> +    xbi->edid_caps = bootsym(boot_edid_caps);
> +    xbi->edid_info = bootsym(boot_edid_info);
> +}
> +
> +xbi_t __init *__init_xbi(u32 mbd_ptr)
> +{
> +    mbd_t *mbd = __va(mbd_ptr);
> +
> +    if ( mbd->boot_loader_name )
> +        xbi_mb.boot_loader_name = __va(mbd->boot_loader_name);
> +
> +    if ( mbd->cmdline )
> +        xbi_mb.cmdline = __va(mbd->cmdline);
> +
> +    init_mmap(&xbi_mb, mbd);
> +
> +    if ( xbi_mb.err_msg )
> +        goto err;
> +
> +    init_video_info(&xbi_mb);
> +
> +    xbi_mb.edd_info_nr = bootsym(boot_edd_info_nr);
> +    xbi_mb.edd_info = bootsym(boot_edd_info);
> +
> +    xbi_mb.mbr_signature_nr = bootsym(boot_mbr_signature_nr);
> +    xbi_mb.mbr_signature = bootsym(boot_mbr_signature);
> +
> +    xbi_mb.mods_nr = mbd->mods_nr;
> +    xbi_mb.mods = __va(mbd->mods);
> +
> +err:
> +    return &xbi_mb;
> +}
> diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c
> index 091d5d1..9cabf0a 100644
> --- a/xen/arch/x86/microcode.c
> +++ b/xen/arch/x86/microcode.c
> @@ -40,8 +40,8 @@
>  #include <asm/setup.h>
>  #include <asm/microcode.h>
>
> -static module_t __initdata ucode_mod;
> -static void *(*__initdata ucode_mod_map)(const module_t *);
> +static boot_module_t __initdata ucode_mod;
> +static void *(*__initdata ucode_mod_map)(const boot_module_t *);
>  static signed int __initdata ucode_mod_idx;
>  static bool_t __initdata ucode_mod_forced;
>  static cpumask_t __initdata init_mask;
> @@ -94,10 +94,9 @@ custom_param("ucode", parse_ucode);
>
>  void __init microcode_scan_module(
>      unsigned long *module_map,
> -    const multiboot_info_t *mbi,
> -    void *(*bootmap)(const module_t *))
> +    const xbi_t *xbi,
> +    void *(*bootmap)(const boot_module_t *))
>  {
> -    module_t *mod = (module_t *)__va(mbi->mods_addr);
>      uint64_t *_blob_start;
>      unsigned long _blob_size;
>      struct cpio_data cd;
> @@ -119,13 +118,13 @@ void __init microcode_scan_module(
>      /*
>       * Try all modules and see whichever could be the microcode blob.
>       */
> -    for ( i = 1 /* Ignore dom0 kernel */; i < mbi->mods_count; i++ )
> +    for ( i = 1 /* Ignore dom0 kernel */; i < xbi->mods_nr; i++ )
>      {
>          if ( !test_bit(i, module_map) )
>              continue;
>
> -        _blob_start = bootmap(&mod[i]);
> -        _blob_size = mod[i].mod_end;
> +        _blob_start = bootmap(&xbi->mods[i]);
> +        _blob_size = xbi->mods[i].end;
>          if ( !_blob_start )
>          {
>              printk("Could not map multiboot module #%d (size: %ld)\n",
> @@ -165,21 +164,19 @@ err:
>  }
>  void __init microcode_grab_module(
>      unsigned long *module_map,
> -    const multiboot_info_t *mbi,
> -    void *(*map)(const module_t *))
> +    const xbi_t *xbi,
> +    void *(*map)(const boot_module_t *))
>  {
> -    module_t *mod = (module_t *)__va(mbi->mods_addr);
> -
>      if ( ucode_mod_idx < 0 )
> -        ucode_mod_idx += mbi->mods_count;
> -    if ( ucode_mod_idx <= 0 || ucode_mod_idx >= mbi->mods_count ||
> +        ucode_mod_idx += xbi->mods_nr;
> +    if ( ucode_mod_idx <= 0 || ucode_mod_idx >= xbi->mods_nr ||
>           !__test_and_clear_bit(ucode_mod_idx, module_map) )
>          goto scan;
> -    ucode_mod = mod[ucode_mod_idx];
> +    ucode_mod = xbi->mods[ucode_mod_idx];
>      ucode_mod_map = map;
>  scan:
>      if ( ucode_scan )
> -        microcode_scan_module(module_map, mbi, map);
> +        microcode_scan_module(module_map, xbi, map);
>  }
>
>  const struct microcode_ops *microcode_ops;
> @@ -345,7 +342,7 @@ int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void) buf, unsigned long len)
>  static void __init _do_microcode_update(unsigned long data)
>  {
>      void *_data = (void *)data;
> -    size_t len = ucode_blob.size ? ucode_blob.size : ucode_mod.mod_end;
> +    size_t len = ucode_blob.size ? ucode_blob.size : ucode_mod.end;
>
>      microcode_update_cpu(_data, len);
>      cpumask_set_cpu(smp_processor_id(), &init_mask);
> @@ -360,7 +357,7 @@ static int __init microcode_init(void)
>      if ( !microcode_ops )
>          return 0;
>
> -    if ( !ucode_mod.mod_end && !ucode_blob.size )
> +    if ( !ucode_mod.end && !ucode_blob.size )
>          return 0;
>
>      data = ucode_blob.size ? ucode_blob.data : ucode_mod_map(&ucode_mod);
> @@ -414,7 +411,7 @@ static int __init microcode_presmp_init(void)
>  {
>      if ( microcode_ops )
>      {
> -        if ( ucode_mod.mod_end || ucode_blob.size )
> +        if ( ucode_mod.end || ucode_blob.size )
>          {
>              void *data;
>              size_t len;
> @@ -427,7 +424,7 @@ static int __init microcode_presmp_init(void)
>              }
>              else
>              {
> -                len = ucode_mod.mod_end;
> +                len = ucode_mod.end;
>                  data = ucode_mod_map(&ucode_mod);
>              }
>              if ( data )
> @@ -447,7 +444,7 @@ static int __init microcode_presmp_init(void)
>                      ucode_blob.data = NULL;
>                  }
>                  else
> -                    ucode_mod.mod_end = 0;
> +                    ucode_mod.end = 0;
>              }
>          }
>
> diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
> index a38e016..a8bcb14 100644
> --- a/xen/arch/x86/mpparse.c
> +++ b/xen/arch/x86/mpparse.c
> @@ -29,6 +29,7 @@
>  #include <asm/mpspec.h>
>  #include <asm/io_apic.h>
>  #include <asm/setup.h>
> +#include <asm/xbi.h>
>
>  #include <mach_apic.h>
>  #include <mach_mpparse.h>
> @@ -676,18 +677,18 @@ static void __init efi_check_config(void)
>  {
>         struct intel_mp_floating *mpf;
>
> -       if (efi.mps == EFI_INVALID_TABLE_ADDR)
> +       if (xbi->mps == EFI_INVALID_TABLE_ADDR)
>                 return;
>
> -       __set_fixmap(FIX_EFI_MPF, PFN_DOWN(efi.mps), __PAGE_HYPERVISOR);
> -       mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)efi.mps & (PAGE_SIZE-1));
> +       __set_fixmap(FIX_EFI_MPF, PFN_DOWN(xbi->mps), __PAGE_HYPERVISOR);
> +       mpf = (void *)fix_to_virt(FIX_EFI_MPF) + ((long)xbi->mps & (PAGE_SIZE-1));
>
>         if (memcmp(mpf->mpf_signature, "_MP_", 4) == 0 &&
>             mpf->mpf_length == 1 &&
>             mpf_checksum((void *)mpf, 16) &&
>             (mpf->mpf_specification == 1 || mpf->mpf_specification == 4)) {
>                 smp_found_config = 1;
> -               printk(KERN_INFO "SMP MP-table at %08lx\n", efi.mps);
> +               printk(KERN_INFO "SMP MP-table at %08lx\n", xbi->mps);
>                 mpf_found = mpf;
>         }
>         else
> diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
> index 2162811..bbfcfd2 100644
> --- a/xen/arch/x86/platform_hypercall.c
> +++ b/xen/arch/x86/platform_hypercall.c
> @@ -30,6 +30,7 @@
>  #include <asm/mtrr.h>
>  #include <asm/io_apic.h>
>  #include <asm/setup.h>
> +#include <asm/xbi.h>
>  #include "cpu/mtrr/mtrr.h"
>  #include <xsm/xsm.h>
>
> @@ -208,10 +209,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>              u16 length;
>
>              ret = -ESRCH;
> -            if ( op->u.firmware_info.index >= bootsym(boot_edd_info_nr) )
> +            if ( op->u.firmware_info.index >= xbi->edd_info_nr )
>                  break;
>
> -            info = bootsym(boot_edd_info) + op->u.firmware_info.index;
> +            info = xbi->edd_info + op->u.firmware_info.index;
>
>              /* Transfer the EDD info block. */
>              ret = -EFAULT;
> @@ -247,10 +248,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>              const struct mbr_signature *sig;
>
>              ret = -ESRCH;
> -            if ( op->u.firmware_info.index >= bootsym(boot_mbr_signature_nr) )
> +            if ( op->u.firmware_info.index >= xbi->mbr_signature_nr )
>                  break;
>
> -            sig = bootsym(boot_mbr_signature) + op->u.firmware_info.index;
> +            sig = xbi->mbr_signature + op->u.firmware_info.index;
>
>              op->u.firmware_info.u.disk_mbr_signature.device = sig->device;
>              op->u.firmware_info.u.disk_mbr_signature.mbr_signature =
> @@ -265,13 +266,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>              ret = -ESRCH;
>              if ( op->u.firmware_info.index != 0 )
>                  break;
> -            if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 )
> +            if ( *(u32 *)xbi->edid_info == 0x13131313 )
>                  break;
>
> -            op->u.firmware_info.u.vbeddc_info.capabilities =
> -                bootsym(boot_edid_caps);
> -            op->u.firmware_info.u.vbeddc_info.edid_transfer_time =
> -                bootsym(boot_edid_caps) >> 8;
> +            op->u.firmware_info.u.vbeddc_info.capabilities = xbi->edid_caps;
> +            op->u.firmware_info.u.vbeddc_info.edid_transfer_time = xbi->edid_caps >> 8;
>
>              ret = 0;
>              if ( __copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
> @@ -279,7 +278,7 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>                   __copy_field_to_guest(u_xenpf_op, op, u.firmware_info.
>                                         u.vbeddc_info.edid_transfer_time) ||
>                   copy_to_compat(op->u.firmware_info.u.vbeddc_info.edid,
> -                                bootsym(boot_edid_info), 128) )
> +                                xbi->edid_info, 128) )
>                  ret = -EFAULT;
>              break;
>          case XEN_FW_EFI_INFO:
> diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
> index 599cf04..b3bf26a 100644
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -12,7 +12,6 @@
>  #include <xen/console.h>
>  #include <xen/serial.h>
>  #include <xen/trace.h>
> -#include <xen/multiboot.h>
>  #include <xen/domain_page.h>
>  #include <xen/version.h>
>  #include <xen/gdbstub.h>
> @@ -49,6 +48,7 @@
>  #include <xen/cpu.h>
>  #include <asm/nmi.h>
>  #include <asm/alternative.h>
> +#include <asm/xbi.h>
>
>  /* opt_nosmp: If true, secondary processors are ignored. */
>  static bool_t __initdata opt_nosmp;
> @@ -93,6 +93,8 @@ unsigned long __initdata highmem_start;
>  size_param("highmem-start", highmem_start);
>  #endif
>
> +xbi_t *xbi;
> +
>  cpumask_t __read_mostly cpu_present_map;
>
>  unsigned long __read_mostly xen_phys_start;
> @@ -138,7 +140,7 @@ static void __init parse_acpi_param(char *s)
>      }
>  }
>
> -static const module_t *__initdata initial_images;
> +static const boot_module_t *__initdata initial_images;
>  static unsigned int __initdata nr_initial_images;
>
>  unsigned long __init initial_images_nrpages(void)
> @@ -147,7 +149,7 @@ unsigned long __init initial_images_nrpages(void)
>      unsigned int i;
>
>      for ( nr = i = 0; i < nr_initial_images; ++i )
> -        nr += PFN_UP(initial_images[i].mod_end);
> +        nr += PFN_UP(initial_images[i].end);
>
>      return nr;
>  }
> @@ -158,10 +160,10 @@ void __init discard_initial_images(void)
>
>      for ( i = 0; i < nr_initial_images; ++i )
>      {
> -        uint64_t start = (uint64_t)initial_images[i].mod_start << PAGE_SHIFT;
> +        uint64_t start = (uint64_t)initial_images[i].start << PAGE_SHIFT;
>
>          init_domheap_pages(start,
> -                           start + PAGE_ALIGN(initial_images[i].mod_end));
> +                           start + PAGE_ALIGN(initial_images[i].end));
>      }
>
>      nr_initial_images = 0;
> @@ -262,14 +264,14 @@ static void __init normalise_cpu_order(void)
>   * Ensure a given physical memory range is present in the bootstrap mappings.
>   * Use superpage mappings to ensure that pagetable memory needn't be allocated.
>   */
> -static void *__init bootstrap_map(const module_t *mod)
> +static void *__init bootstrap_map(const boot_module_t *mod)
>  {
>      static unsigned long __initdata map_cur = BOOTSTRAP_MAP_BASE;
>      uint64_t start, end, mask = (1L << L2_PAGETABLE_SHIFT) - 1;
>      void *ret;
>
>      if ( system_state != SYS_STATE_early_boot )
> -        return mod ? mfn_to_virt(mod->mod_start) : NULL;
> +        return mod ? mfn_to_virt(mod->start) : NULL;
>
>      if ( !mod )
>      {
> @@ -278,8 +280,8 @@ static void *__init bootstrap_map(const module_t *mod)
>          return NULL;
>      }
>
> -    start = (uint64_t)mod->mod_start << PAGE_SHIFT;
> -    end = start + mod->mod_end;
> +    start = (uint64_t)mod->start << PAGE_SHIFT;
> +    end = start + mod->end;
>      if ( start >= end )
>          return NULL;
>
> @@ -309,25 +311,25 @@ static void *__init move_memory(
>
>      while ( size )
>      {
> -        module_t mod;
> +        boot_module_t mod;
>          unsigned int soffs = src & mask;
>          unsigned int doffs = dst & mask;
>          unsigned int sz;
>          void *d, *s;
>
> -        mod.mod_start = (src - soffs) >> PAGE_SHIFT;
> -        mod.mod_end = soffs + size;
> -        if ( mod.mod_end > blksz )
> -            mod.mod_end = blksz;
> -        sz = mod.mod_end - soffs;
> +        mod.start = (src - soffs) >> PAGE_SHIFT;
> +        mod.end = soffs + size;
> +        if ( mod.end > blksz )
> +            mod.end = blksz;
> +        sz = mod.end - soffs;
>          s = bootstrap_map(&mod);
>
> -        mod.mod_start = (dst - doffs) >> PAGE_SHIFT;
> -        mod.mod_end = doffs + size;
> -        if ( mod.mod_end > blksz )
> -            mod.mod_end = blksz;
> -        if ( sz > mod.mod_end - doffs )
> -            sz = mod.mod_end - doffs;
> +        mod.start = (dst - doffs) >> PAGE_SHIFT;
> +        mod.end = doffs + size;
> +        if ( mod.end > blksz )
> +            mod.end = blksz;
> +        if ( sz > mod.end - doffs )
> +            sz = mod.end - doffs;
>          d = bootstrap_map(&mod);
>
>          memmove(d + doffs, s + soffs, sz);
> @@ -346,7 +348,7 @@ static void *__init move_memory(
>  }
>
>  static uint64_t __init consider_modules(
> -    uint64_t s, uint64_t e, uint32_t size, const module_t *mod,
> +    uint64_t s, uint64_t e, uint32_t size, const boot_module_t *mod,
>      unsigned int nr_mods, unsigned int this_mod)
>  {
>      unsigned int i;
> @@ -356,8 +358,8 @@ static uint64_t __init consider_modules(
>
>      for ( i = 0; i < nr_mods ; ++i )
>      {
> -        uint64_t start = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
> -        uint64_t end = start + PAGE_ALIGN(mod[i].mod_end);
> +        uint64_t start = (uint64_t)mod[i].start << PAGE_SHIFT;
> +        uint64_t end = start + PAGE_ALIGN(mod[i].end);
>
>          if ( i == this_mod )
>              continue;
> @@ -406,76 +408,6 @@ void set_pdx_range(unsigned long smfn, unsigned long emfn)
>  /* A temporary copy of the e820 map that we can mess with during bootstrap. */
>  static struct e820map __initdata boot_e820;
>
> -struct boot_video_info {
> -    u8  orig_x;             /* 0x00 */
> -    u8  orig_y;             /* 0x01 */
> -    u8  orig_video_mode;    /* 0x02 */
> -    u8  orig_video_cols;    /* 0x03 */
> -    u8  orig_video_lines;   /* 0x04 */
> -    u8  orig_video_isVGA;   /* 0x05 */
> -    u16 orig_video_points;  /* 0x06 */
> -
> -    /* VESA graphic mode -- linear frame buffer */
> -    u32 capabilities;       /* 0x08 */
> -    u16 lfb_linelength;     /* 0x0c */
> -    u16 lfb_width;          /* 0x0e */
> -    u16 lfb_height;         /* 0x10 */
> -    u16 lfb_depth;          /* 0x12 */
> -    u32 lfb_base;           /* 0x14 */
> -    u32 lfb_size;           /* 0x18 */
> -    u8  red_size;           /* 0x1c */
> -    u8  red_pos;            /* 0x1d */
> -    u8  green_size;         /* 0x1e */
> -    u8  green_pos;          /* 0x1f */
> -    u8  blue_size;          /* 0x20 */
> -    u8  blue_pos;           /* 0x21 */
> -    u8  rsvd_size;          /* 0x22 */
> -    u8  rsvd_pos;           /* 0x23 */
> -    u16 vesapm_seg;         /* 0x24 */
> -    u16 vesapm_off;         /* 0x26 */
> -    u16 vesa_attrib;        /* 0x28 */
> -};
> -extern struct boot_video_info boot_vid_info;
> -
> -static void __init parse_video_info(void)
> -{
> -    struct boot_video_info *bvi = &bootsym(boot_vid_info);
> -
> -    /* The EFI loader fills vga_console_info directly. */
> -    if ( efi_enabled )
> -        return;
> -
> -    if ( (bvi->orig_video_isVGA == 1) && (bvi->orig_video_mode == 3) )
> -    {
> -        vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3;
> -        vga_console_info.u.text_mode_3.font_height = bvi->orig_video_points;
> -        vga_console_info.u.text_mode_3.cursor_x = bvi->orig_x;
> -        vga_console_info.u.text_mode_3.cursor_y = bvi->orig_y;
> -        vga_console_info.u.text_mode_3.rows = bvi->orig_video_lines;
> -        vga_console_info.u.text_mode_3.columns = bvi->orig_video_cols;
> -    }
> -    else if ( bvi->orig_video_isVGA == 0x23 )
> -    {
> -        vga_console_info.video_type = XEN_VGATYPE_VESA_LFB;
> -        vga_console_info.u.vesa_lfb.width = bvi->lfb_width;
> -        vga_console_info.u.vesa_lfb.height = bvi->lfb_height;
> -        vga_console_info.u.vesa_lfb.bytes_per_line = bvi->lfb_linelength;
> -        vga_console_info.u.vesa_lfb.bits_per_pixel = bvi->lfb_depth;
> -        vga_console_info.u.vesa_lfb.lfb_base = bvi->lfb_base;
> -        vga_console_info.u.vesa_lfb.lfb_size = bvi->lfb_size;
> -        vga_console_info.u.vesa_lfb.red_pos = bvi->red_pos;
> -        vga_console_info.u.vesa_lfb.red_size = bvi->red_size;
> -        vga_console_info.u.vesa_lfb.green_pos = bvi->green_pos;
> -        vga_console_info.u.vesa_lfb.green_size = bvi->green_size;
> -        vga_console_info.u.vesa_lfb.blue_pos = bvi->blue_pos;
> -        vga_console_info.u.vesa_lfb.blue_size = bvi->blue_size;
> -        vga_console_info.u.vesa_lfb.rsvd_pos = bvi->rsvd_pos;
> -        vga_console_info.u.vesa_lfb.rsvd_size = bvi->rsvd_size;
> -        vga_console_info.u.vesa_lfb.gbl_caps = bvi->capabilities;
> -        vga_console_info.u.vesa_lfb.mode_attrs = bvi->vesa_attrib;
> -    }
> -}
> -
>  static void __init kexec_reserve_area(struct e820map *e820)
>  {
>      unsigned long kdump_start = kexec_crash_area.start;
> @@ -540,15 +472,12 @@ static char * __init cmdline_cook(char *p, char *loader_name)
>      return p;
>  }
>
> -void __init noreturn __start_xen(unsigned long mbi_p)
> +void __init noreturn __start_xen(xbi_t *xbi_start)
>  {
> -    char *memmap_type = NULL;
> -    char *cmdline, *kextra, *loader;
> +    char *cmdline, *kextra;
>      unsigned int initrdidx, domcr_flags = DOMCRF_s3_integrity;
> -    multiboot_info_t *mbi = __va(mbi_p);
> -    module_t *mod = (module_t *)__va(mbi->mods_addr);
>      unsigned long nr_pages, raw_max_page, modules_headroom, *module_map;
> -    int i, j, e820_warn = 0, bytes = 0;
> +    int i, j;
>      bool_t acpi_boot_table_init_done = 0;
>      struct domain *dom0;
>      struct ns16550_defaults ns16550 = {
> @@ -573,13 +502,16 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>
>      /* Full exception support from here on in. */
>
> -    loader = (mbi->flags & MBI_LOADERNAME)
> -        ? (char *)__va(mbi->boot_loader_name) : "unknown";
> +    if ( !efi_enabled )
> +        xbi = xbi_start;
> +    else
> +    {
> +        xbi = __va(xbi_start);
> +        xbi->cmdline = __va(xbi->cmdline);
> +    }
>
>      /* Parse the command-line options. */
> -    cmdline = cmdline_cook((mbi->flags & MBI_CMDLINE) ?
> -                           __va(mbi->cmdline) : NULL,
> -                           loader);
> +    cmdline = cmdline_cook(xbi->cmdline, xbi->boot_loader_name);
>      if ( (kextra = strstr(cmdline, " -- ")) != NULL )
>      {
>          /*
> @@ -597,8 +529,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * allocing any xenheap structures wanted in lower memory. */
>      kexec_early_calculations();
>
> -    parse_video_info();
> -
>      if ( cpu_has_efer )
>          rdmsrl(MSR_EFER, this_cpu(efer));
>      asm volatile ( "mov %%cr4,%0" : "=r" (this_cpu(cr4)) );
> @@ -613,27 +543,33 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      ehci_dbgp_init();
>      console_init_preirq();
>
> -    printk("Bootloader: %s\n", loader);
> +    if ( xbi->err_msg )
> +        panic(xbi->err_msg);
> +
> +    if ( xbi->warn_msg )
> +        printk(xbi->warn_msg);
> +
> +    printk("Bootloader: %s\n", xbi->boot_loader_name);
>
> -    printk("Command line: %s\n", cmdline);
> +    printk("Command line: %s\n", xbi->cmdline ? xbi->cmdline : "NONE");
>
>      printk("Video information:\n");
>
>      /* Print VGA display mode information. */
> -    switch ( vga_console_info.video_type )
> +    switch ( xbi->vga_console_info.video_type )
>      {
>      case XEN_VGATYPE_TEXT_MODE_3:
>          printk(" VGA is text mode %dx%d, font 8x%d\n",
> -               vga_console_info.u.text_mode_3.columns,
> -               vga_console_info.u.text_mode_3.rows,
> -               vga_console_info.u.text_mode_3.font_height);
> +               xbi->vga_console_info.u.text_mode_3.columns,
> +               xbi->vga_console_info.u.text_mode_3.rows,
> +               xbi->vga_console_info.u.text_mode_3.font_height);
>          break;
>      case XEN_VGATYPE_VESA_LFB:
>      case XEN_VGATYPE_EFI_LFB:
>          printk(" VGA is graphics mode %dx%d, %d bpp\n",
> -               vga_console_info.u.vesa_lfb.width,
> -               vga_console_info.u.vesa_lfb.height,
> -               vga_console_info.u.vesa_lfb.bits_per_pixel);
> +               xbi->vga_console_info.u.vesa_lfb.width,
> +               xbi->vga_console_info.u.vesa_lfb.height,
> +               xbi->vga_console_info.u.vesa_lfb.bits_per_pixel);
>          break;
>      default:
>          printk(" No VGA detected\n");
> @@ -641,15 +577,15 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      }
>
>      /* Print VBE/DDC EDID information. */
> -    if ( bootsym(boot_edid_caps) != 0x1313 )
> +    if ( xbi->edid_caps != 0x1313 )
>      {
> -        u16 caps = bootsym(boot_edid_caps);
> +        u16 caps = xbi->edid_caps;
>          printk(" VBE/DDC methods:%s%s%s; ",
>                 (caps & 1) ? " V1" : "",
>                 (caps & 2) ? " V2" : "",
>                 !(caps & 3) ? " none" : "");
>          printk("EDID transfer time: %d seconds\n", caps >> 8);
> -        if ( *(u32 *)bootsym(boot_edid_info) == 0x13131313 )
> +        if ( *(u32 *)xbi->edid_info == 0x13131313 )
>          {
>              printk(" EDID info not retrieved because ");
>              if ( !(caps & 3) )
> @@ -662,13 +598,11 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      }
>
>      printk("Disc information:\n");
> -    printk(" Found %d MBR signatures\n",
> -           bootsym(boot_mbr_signature_nr));
> -    printk(" Found %d EDD information structures\n",
> -           bootsym(boot_edd_info_nr));
> +    printk(" Found %d MBR signatures\n", xbi->mbr_signature_nr);
> +    printk(" Found %d EDD information structures\n", xbi->edd_info_nr);
>
>      /* Check that we have at least one Multiboot module. */
> -    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
> +    if ( !xbi->mods_nr )
>          panic("dom0 kernel not specified. Check bootloader configuration.");
>
>      if ( ((unsigned long)cpu0_stack & (STACK_SIZE-1)) != 0 )
> @@ -686,77 +620,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          /* Make boot page tables match non-EFI boot. */
>          l3_bootmap[l3_table_offset(BOOTSTRAP_MAP_BASE)] =
>              l3e_from_paddr(__pa(l2_bootmap), __PAGE_HYPERVISOR);
> -
> -        memmap_type = loader;
>      }
> -    else if ( e820_raw_nr != 0 )
> -    {
> -        memmap_type = "Xen-e820";
> -    }
> -    else if ( mbi->flags & MBI_MEMMAP )
> -    {
> -        memmap_type = "Multiboot-e820";
> -        while ( (bytes < mbi->mmap_length) && (e820_raw_nr < E820MAX) )
> -        {
> -            memory_map_t *map = __va(mbi->mmap_addr + bytes);
> -
> -            /*
> -             * This is a gross workaround for a BIOS bug. Some bootloaders do
> -             * not write e820 map entries into pre-zeroed memory. This is
> -             * okay if the BIOS fills in all fields of the map entry, but
> -             * some broken BIOSes do not bother to write the high word of
> -             * the length field if the length is smaller than 4GB. We
> -             * detect and fix this by flagging sections below 4GB that
> -             * appear to be larger than 4GB in size.
> -             */
> -            if ( (map->base_addr_high == 0) && (map->length_high != 0) )
> -            {
> -                if ( !e820_warn )
> -                {
> -                    printk("WARNING: Buggy e820 map detected and fixed "
> -                           "(truncated length fields).\n");
> -                    e820_warn = 1;
> -                }
> -                map->length_high = 0;
> -            }
> -
> -            e820_raw[e820_raw_nr].addr =
> -                ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
> -            e820_raw[e820_raw_nr].size =
> -                ((u64)map->length_high << 32) | (u64)map->length_low;
> -            e820_raw[e820_raw_nr].type = map->type;
> -            e820_raw_nr++;
> -
> -            bytes += map->size + 4;
> -        }
> -    }
> -    else if ( bootsym(lowmem_kb) )
> -    {
> -        memmap_type = "Xen-e801";
> -        e820_raw[0].addr = 0;
> -        e820_raw[0].size = bootsym(lowmem_kb) << 10;
> -        e820_raw[0].type = E820_RAM;
> -        e820_raw[1].addr = 0x100000;
> -        e820_raw[1].size = bootsym(highmem_kb) << 10;
> -        e820_raw[1].type = E820_RAM;
> -        e820_raw_nr = 2;
> -    }
> -    else if ( mbi->flags & MBI_MEMLIMITS )
> -    {
> -        memmap_type = "Multiboot-e801";
> -        e820_raw[0].addr = 0;
> -        e820_raw[0].size = mbi->mem_lower << 10;
> -        e820_raw[0].type = E820_RAM;
> -        e820_raw[1].addr = 0x100000;
> -        e820_raw[1].size = mbi->mem_upper << 10;
> -        e820_raw[1].type = E820_RAM;
> -        e820_raw_nr = 2;
> -    }
> -    else
> -        panic("Bootloader provided no memory information.");
>
>      /* Sanitise the raw E820 map to produce a final clean version. */
> -    max_page = raw_max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
> +    max_page = raw_max_page = init_e820(xbi->mmap_type, xbi->e820map, &xbi->e820map_nr);
>
>      /* Create a temporary copy of the E820 map. */
>      memcpy(&boot_e820, &e820, sizeof(e820));
> @@ -769,8 +636,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      set_kexec_crash_area_size((u64)nr_pages << PAGE_SHIFT);
>      kexec_reserve_area(&boot_e820);
>
> -    initial_images = mod;
> -    nr_initial_images = mbi->mods_count;
> +    nr_initial_images = xbi->mods_nr;
> +    initial_images = xbi->mods;
>
>      /*
>       * Iterate backwards over all superpage-aligned RAM regions.
> @@ -785,16 +652,15 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * we can relocate the dom0 kernel and other multiboot modules. Also, on
>       * x86/64, we relocate Xen to higher memory.
>       */
> -    for ( i = 0; !efi_enabled && i < mbi->mods_count; i++ )
> +    for ( i = 0; !efi_enabled && i < xbi->mods_nr; i++ )
>      {
> -        if ( mod[i].mod_start & (PAGE_SIZE - 1) )
> +        if ( xbi->mods[i].start & (PAGE_SIZE - 1) )
>              panic("Bootloader didn't honor module alignment request.");
> -        mod[i].mod_end -= mod[i].mod_start;
> -        mod[i].mod_start >>= PAGE_SHIFT;
> -        mod[i].reserved = 0;
> +        xbi->mods[i].end -= xbi->mods[i].start;
> +        xbi->mods[i].start >>= PAGE_SHIFT;
>      }
>
> -    modules_headroom = bzimage_headroom(bootstrap_map(mod), mod->mod_end);
> +    modules_headroom = bzimage_headroom(bootstrap_map(xbi->mods), xbi->mods->end);
>      bootstrap_map(NULL);
>
>  #ifndef highmem_start
> @@ -835,7 +701,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          {
>              /* Don't overlap with modules. */
>              end = consider_modules(s, e, reloc_size + mask,
> -                                   mod, mbi->mods_count, -1);
> +                                   xbi->mods, xbi->mods_nr, -1);
>              end &= ~mask;
>          }
>          else
> @@ -923,36 +789,36 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          }
>
>          /* Is the region suitable for relocating the multiboot modules? */
> -        for ( j = mbi->mods_count - 1; j >= 0; j-- )
> +        for ( j = xbi->mods_nr - 1; j >= 0; j-- )
>          {
>              unsigned long headroom = j ? 0 : modules_headroom;
> -            unsigned long size = PAGE_ALIGN(headroom + mod[j].mod_end);
> +            unsigned long size = PAGE_ALIGN(headroom + xbi->mods[j].end);
>
> -            if ( mod[j].reserved )
> +            if ( xbi->mods[j].relocated )
>                  continue;
>
>              /* Don't overlap with other modules. */
> -            end = consider_modules(s, e, size, mod, mbi->mods_count, j);
> +            end = consider_modules(s, e, size, xbi->mods, xbi->mods_nr, j);
>
>              if ( highmem_start && end > highmem_start )
>                  continue;
>
>              if ( s < end &&
>                   (headroom ||
> -                  ((end - size) >> PAGE_SHIFT) > mod[j].mod_start) )
> +                  ((end - size) >> PAGE_SHIFT) > xbi->mods[j].start) )
>              {
>                  move_memory(end - size + headroom,
> -                            (uint64_t)mod[j].mod_start << PAGE_SHIFT,
> -                            mod[j].mod_end, 0);
> -                mod[j].mod_start = (end - size) >> PAGE_SHIFT;
> -                mod[j].mod_end += headroom;
> -                mod[j].reserved = 1;
> +                            (uint64_t)xbi->mods[j].start << PAGE_SHIFT,
> +                            xbi->mods[j].end, 0);
> +                xbi->mods[j].start = (end - size) >> PAGE_SHIFT;
> +                xbi->mods[j].end += headroom;
> +                xbi->mods[j].relocated = 1;
>              }
>          }
>
>          /* Don't overlap with modules. */
>          e = consider_modules(s, e, PAGE_ALIGN(kexec_crash_area.size),
> -                             mod, mbi->mods_count, -1);
> +                             xbi->mods, xbi->mods_nr, -1);
>          if ( !kexec_crash_area.start && (s < e) )
>          {
>              e = (e - kexec_crash_area.size) & PAGE_MASK;
> @@ -960,18 +826,18 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          }
>      }
>
> -    if ( modules_headroom && !mod->reserved )
> +    if ( modules_headroom && !xbi->mods->relocated )
>          panic("Not enough memory to relocate the dom0 kernel image.");
> -    for ( i = 0; i < mbi->mods_count; ++i )
> +    for ( i = 0; i < xbi->mods_nr; ++i )
>      {
> -        uint64_t s = (uint64_t)mod[i].mod_start << PAGE_SHIFT;
> +        uint64_t s = (uint64_t)xbi->mods[i].start << PAGE_SHIFT;
>
> -        reserve_e820_ram(&boot_e820, s, s + PAGE_ALIGN(mod[i].mod_end));
> +        reserve_e820_ram(&boot_e820, s, s + PAGE_ALIGN(xbi->mods[i].end));
>      }
>
>      if ( !xen_phys_start )
>          panic("Not enough memory to relocate Xen.");
> -    reserve_e820_ram(&boot_e820, efi_enabled ? mbi->mem_upper : __pa(&_start),
> +    reserve_e820_ram(&boot_e820, efi_enabled ? xbi->mem_upper : __pa(&_start),
>                       __pa(&_end));
>
>      /* Late kexec reservation (dynamic start address). */
> @@ -1017,10 +883,10 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>                      ASSERT(j);
>                  }
>                  map_e = boot_e820.map[j].addr + boot_e820.map[j].size;
> -                for ( j = 0; j < mbi->mods_count; ++j )
> +                for ( j = 0; j < xbi->mods_nr; ++j )
>                  {
> -                    uint64_t end = pfn_to_paddr(mod[j].mod_start) +
> -                                   mod[j].mod_end;
> +                    uint64_t end = pfn_to_paddr(xbi->mods[j].start) +
> +                                   xbi->mods[j].end;
>
>                      if ( map_e < end )
>                          map_e = end;
> @@ -1093,13 +959,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>          }
>      }
>
> -    for ( i = 0; i < mbi->mods_count; ++i )
> +    for ( i = 0; i < xbi->mods_nr; ++i )
>      {
> -        set_pdx_range(mod[i].mod_start,
> -                      mod[i].mod_start + PFN_UP(mod[i].mod_end));
> -        map_pages_to_xen((unsigned long)mfn_to_virt(mod[i].mod_start),
> -                         mod[i].mod_start,
> -                         PFN_UP(mod[i].mod_end), PAGE_HYPERVISOR);
> +        set_pdx_range(xbi->mods[i].start,
> +                      xbi->mods[i].start + PFN_UP(xbi->mods[i].end));
> +        map_pages_to_xen((unsigned long)mfn_to_virt(xbi->mods[i].start),
> +                         xbi->mods[i].start,
> +                         PFN_UP(xbi->mods[i].end), PAGE_HYPERVISOR);
>      }
>
>      if ( kexec_crash_area.size )
> @@ -1253,13 +1119,13 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>
>      init_IRQ();
>
> -    module_map = xmalloc_array(unsigned long, BITS_TO_LONGS(mbi->mods_count));
> -    bitmap_fill(module_map, mbi->mods_count);
> +    module_map = xmalloc_array(unsigned long, BITS_TO_LONGS(xbi->mods_nr));
> +    bitmap_fill(module_map, xbi->mods_nr);
>      __clear_bit(0, module_map); /* Dom0 kernel is always first */
>
> -    xsm_multiboot_init(module_map, mbi, bootstrap_map);
> +    xsm_multiboot_init(module_map, xbi, bootstrap_map);
>
> -    microcode_grab_module(module_map, mbi, bootstrap_map);
> +    microcode_grab_module(module_map, xbi, bootstrap_map);
>
>      timer_init();
>
> @@ -1364,12 +1230,12 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      dom0->target = NULL;
>
>      /* Grab the DOM0 command line. */
> -    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
> +    cmdline = (char *)(xbi->mods[0].cmdline ? __va(xbi->mods[0].cmdline) : NULL);
>      if ( (cmdline != NULL) || (kextra != NULL) )
>      {
>          static char __initdata dom0_cmdline[MAX_GUEST_CMDLINE];
>
> -        cmdline = cmdline_cook(cmdline, loader);
> +        cmdline = cmdline_cook(cmdline, xbi->boot_loader_name);
>          safe_strcpy(dom0_cmdline, cmdline);
>
>          if ( kextra != NULL )
> @@ -1396,8 +1262,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>      if ( xen_cpuidle )
>          xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
>
> -    initrdidx = find_first_bit(module_map, mbi->mods_count);
> -    if ( bitmap_weight(module_map, mbi->mods_count) > 1 )
> +    initrdidx = find_first_bit(module_map, xbi->mods_nr);
> +    if ( bitmap_weight(module_map, xbi->mods_nr) > 1 )
>          printk(XENLOG_WARNING
>                 "Multiple initrd candidates, picking module #%u\n",
>                 initrdidx);
> @@ -1414,9 +1280,9 @@ void __init noreturn __start_xen(unsigned long mbi_p)
>       * We're going to setup domain0 using the module(s) that we stashed safely
>       * above our heap. The second module, if present, is an initrd ramdisk.
>       */
> -    if ( construct_dom0(dom0, mod, modules_headroom,
> -                        (initrdidx > 0) && (initrdidx < mbi->mods_count)
> -                        ? mod + initrdidx : NULL,
> +    if ( construct_dom0(dom0, xbi->mods, modules_headroom,
> +                        (initrdidx > 0) && (initrdidx < xbi->mods_nr)
> +                        ? xbi->mods + initrdidx : NULL,
>                          bootstrap_map, cmdline) != 0)
>          panic("Could not set up DOM0 guest OS");
>
> diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c
> index 3994f4d..2123eb3 100644
> --- a/xen/arch/x86/x86_64/asm-offsets.c
> +++ b/xen/arch/x86/x86_64/asm-offsets.c
> @@ -12,7 +12,7 @@
>  #include <compat/xen.h>
>  #include <asm/fixmap.h>
>  #include <asm/hardirq.h>
> -#include <xen/multiboot.h>
> +#include <asm/mbd.h>
>
>  #define DEFINE(_sym, _val)                                                 \
>      asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \
> @@ -163,6 +163,5 @@ void __dummy__(void)
>      OFFSET(CPUINFO_features, struct cpuinfo_x86, x86_capability);
>      BLANK();
>
> -    OFFSET(MB_flags, multiboot_info_t, flags);
> -    OFFSET(MB_cmdline, multiboot_info_t, cmdline);
> +    OFFSET(MBD_cmdline, mbd_t, cmdline);
>  }
> diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
> index 93c983c..f034e1a 100644
> --- a/xen/drivers/acpi/osl.c
> +++ b/xen/drivers/acpi/osl.c
> @@ -39,6 +39,7 @@
>  #include <xen/domain_page.h>
>  #include <xen/efi.h>
>  #include <xen/vmap.h>
> +#include <asm/xbi.h>
>
>  #define _COMPONENT             ACPI_OS_SERVICES
>  ACPI_MODULE_NAME("osl")
> @@ -67,10 +68,10 @@ void __init acpi_os_vprintf(const char *fmt, va_list args)
>  acpi_physical_address __init acpi_os_get_root_pointer(void)
>  {
>         if (efi_enabled) {
> -               if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
> -                       return efi.acpi20;
> -               else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
> -                       return efi.acpi;
> +               if (xbi->acpi20 != EFI_INVALID_TABLE_ADDR)
> +                       return xbi->acpi20;
> +               else if (xbi->acpi != EFI_INVALID_TABLE_ADDR)
> +                       return xbi->acpi;
>                 else {
>                         printk(KERN_ERR PREFIX
>                                "System description tables not found\n");
> diff --git a/xen/drivers/video/vesa.c b/xen/drivers/video/vesa.c
> index 575db62..8941ac3 100644
> --- a/xen/drivers/video/vesa.c
> +++ b/xen/drivers/video/vesa.c
> @@ -12,10 +12,11 @@
>  #include <xen/vga.h>
>  #include <asm/io.h>
>  #include <asm/page.h>
> +#include <asm/xbi.h>
>  #include "font.h"
>  #include "lfb.h"
>
> -#define vlfb_info    vga_console_info.u.vesa_lfb
> +#define vlfb_info    (xbi->vga_console_info.u.vesa_lfb)
>
>  static void lfb_flush(void);
>
> @@ -43,7 +44,7 @@ void __init vesa_early_init(void)
>  {
>      unsigned int vram_vmode;
>
> -    vga_compat = !(vga_console_info.u.vesa_lfb.gbl_caps & 2);
> +    vga_compat = !(xbi->vga_console_info.u.vesa_lfb.gbl_caps & 2);
>
>      if ( (vlfb_info.bits_per_pixel < 8) || (vlfb_info.bits_per_pixel > 32) )
>          return;
> diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c
> index 40e5963..feb9b31 100644
> --- a/xen/drivers/video/vga.c
> +++ b/xen/drivers/video/vga.c
> @@ -11,9 +11,7 @@
>  #include <xen/vga.h>
>  #include <xen/pci.h>
>  #include <asm/io.h>
> -
> -/* Filled in by arch boot code. */
> -struct xen_vga_console_info vga_console_info;
> +#include <asm/xbi.h>
>
>  static int vgacon_keep;
>  static unsigned int xpos, ypos;
> @@ -75,15 +73,15 @@ void __init video_init(void)
>              vgacon_keep = 1;
>      }
>
> -    switch ( vga_console_info.video_type )
> +    switch ( xbi->vga_console_info.video_type )
>      {
>      case XEN_VGATYPE_TEXT_MODE_3:
>          if ( page_is_ram_type(paddr_to_pfn(0xB8000), RAM_TYPE_CONVENTIONAL) ||
>               ((video = ioremap(0xB8000, 0x8000)) == NULL) )
>              return;
>          outw(0x200a, 0x3d4); /* disable cursor */
> -        columns = vga_console_info.u.text_mode_3.columns;
> -        lines   = vga_console_info.u.text_mode_3.rows;
> +        columns = xbi->vga_console_info.u.text_mode_3.columns;
> +        lines   = xbi->vga_console_info.u.text_mode_3.rows;
>          memset(video, 0, columns * lines * 2);
>          video_puts = vga_text_puts;
>          break;
> @@ -92,7 +90,7 @@ void __init video_init(void)
>          vesa_early_init();
>          break;
>      default:
> -        memset(&vga_console_info, 0, sizeof(vga_console_info));
> +        memset(&xbi->vga_console_info, 0, sizeof(xbi->vga_console_info));
>          break;
>      }
>  }
> @@ -163,7 +161,7 @@ void __init video_endboot(void)
>              }
>      }
>
> -    switch ( vga_console_info.video_type )
> +    switch ( xbi->vga_console_info.video_type )
>      {
>      case XEN_VGATYPE_TEXT_MODE_3:
>          if ( !vgacon_keep )
> @@ -206,6 +204,6 @@ static void vga_text_puts(const char *s)
>
>  int __init fill_console_start_info(struct dom0_vga_console_info *ci)
>  {
> -    memcpy(ci, &vga_console_info, sizeof(*ci));
> +    memcpy(ci, &xbi->vga_console_info, sizeof(*ci));
>      return 1;
>  }
> diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
> index 210ff57..ae68322 100644
> --- a/xen/include/asm-x86/config.h
> +++ b/xen/include/asm-x86/config.h
> @@ -119,8 +119,6 @@ extern unsigned int trampoline_xen_phys_start;
>  extern unsigned char trampoline_cpu_started;
>  extern char wakeup_start[];
>  extern unsigned int video_mode, video_flags;
> -extern unsigned short boot_edid_caps;
> -extern unsigned char boot_edid_info[128];
>  #endif
>
>  #define asmlinkage
> diff --git a/xen/include/asm-x86/e820.h b/xen/include/asm-x86/e820.h
> index 08b413d..5d3683a 100644
> --- a/xen/include/asm-x86/e820.h
> +++ b/xen/include/asm-x86/e820.h
> @@ -33,12 +33,4 @@ extern int e820_add_range(
>  extern unsigned long init_e820(const char *, struct e820entry *, int *);
>  extern struct e820map e820;
>
> -/* These symbols live in the boot trampoline. */
> -extern struct e820entry e820map[];
> -extern int e820nr;
> -extern unsigned int lowmem_kb, highmem_kb;
> -
> -#define e820_raw bootsym(e820map)
> -#define e820_raw_nr bootsym(e820nr)
> -
>  #endif /*__E820_HEADER*/
> diff --git a/xen/include/asm-x86/edd.h b/xen/include/asm-x86/edd.h
> index afaa237..e8361a5 100644
> --- a/xen/include/asm-x86/edd.h
> +++ b/xen/include/asm-x86/edd.h
> @@ -143,12 +143,6 @@ struct __packed mbr_signature {
>      u32 signature;
>  };
>
> -/* These all reside in the boot trampoline. Access via bootsym(). */
> -extern struct mbr_signature boot_mbr_signature[];
> -extern u8 boot_mbr_signature_nr;
> -extern struct edd_info boot_edd_info[];
> -extern u8 boot_edd_info_nr;
> -
>  #endif /* __ASSEMBLY__ */
>
>  /* Maximum number of EDD information structures at boot_edd_info. */
> diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h
> index 8f8c6f3..88e9124 100644
> --- a/xen/include/asm-x86/setup.h
> +++ b/xen/include/asm-x86/setup.h
> @@ -1,7 +1,7 @@
>  #ifndef __X86_SETUP_H_
>  #define __X86_SETUP_H_
>
> -#include <xen/multiboot.h>
> +#include <asm/xbi.h>
>
>  extern unsigned long xenheap_initial_phys_start;
>
> @@ -27,9 +27,9 @@ void vesa_mtrr_init(void);
>
>  int construct_dom0(
>      struct domain *d,
> -    const module_t *kernel, unsigned long kernel_headroom,
> -    module_t *initrd,
> -    void *(*bootstrap_map)(const module_t *),
> +    const boot_module_t *kernel, unsigned long kernel_headroom,
> +    boot_module_t *initrd,
> +    void *(*bootstrap_map)(const boot_module_t *),
>      char *cmdline);
>
>  unsigned long initial_images_nrpages(void);
> @@ -38,7 +38,7 @@ void discard_initial_images(void);
>  int xen_in_range(unsigned long mfn);
>
>  void microcode_grab_module(
> -    unsigned long *, const multiboot_info_t *, void *(*)(const module_t *));
> +    unsigned long *, const xbi_t *, void *(*)(const boot_module_t *));
>
>  extern uint8_t kbd_shift_flags;
>
> diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
> index 8a2b788..64d2dea 100644
> --- a/xen/include/xen/efi.h
> +++ b/xen/include/xen/efi.h
> @@ -9,16 +9,6 @@ extern const bool_t efi_enabled;
>
>  #define EFI_INVALID_TABLE_ADDR (~0UL)
>
> -/* Add fields here only if they need to be referenced from non-EFI code. */
> -struct efi {
> -    unsigned long mps;          /* MPS table */
> -    unsigned long acpi;         /* ACPI table (IA64 ext 0.71) */
> -    unsigned long acpi20;       /* ACPI table (ACPI 2.0) */
> -    unsigned long smbios;       /* SM BIOS table */
> -};
> -
> -extern struct efi efi;
> -
>  #ifndef __ASSEMBLY__
>
>  union xenpf_efi_info;
> diff --git a/xen/include/xen/vga.h b/xen/include/xen/vga.h
> index f72b63d..3d5c331 100644
> --- a/xen/include/xen/vga.h
> +++ b/xen/include/xen/vga.h
> @@ -11,8 +11,4 @@
>
>  #include <xen/video.h>
>
> -#ifdef CONFIG_VGA
> -extern struct xen_vga_console_info vga_console_info;
> -#endif
> -
>  #endif /* _XEN_VGA_H */
> diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
> index a85045d..87f3729 100644
> --- a/xen/include/xsm/xsm.h
> +++ b/xen/include/xsm/xsm.h
> @@ -16,7 +16,7 @@
>  #define __XSM_H__
>
>  #include <xen/sched.h>
> -#include <xen/multiboot.h>
> +#include <asm/xbi.h>
>
>  typedef void xsm_op_t;
>  DEFINE_XEN_GUEST_HANDLE(xsm_op_t);
> @@ -659,11 +659,11 @@ static inline int xsm_ioport_mapping (xsm_default_t def, struct domain *d, uint3
>
>  #ifdef CONFIG_MULTIBOOT
>  extern int xsm_multiboot_init(unsigned long *module_map,
> -                              const multiboot_info_t *mbi,
> -                              void *(*bootstrap_map)(const module_t *));
> +                              const xbi_t *xbi,
> +                              void *(*bootstrap_map)(const boot_module_t *));
>  extern int xsm_multiboot_policy_init(unsigned long *module_map,
> -                                     const multiboot_info_t *mbi,
> -                                     void *(*bootstrap_map)(const module_t *));
> +                                     const xbi_t *xbi,
> +                                     void *(*bootstrap_map)(const boot_module_t *));
>  #endif
>
>  #ifdef HAS_DEVICE_TREE
> @@ -683,8 +683,8 @@ extern void xsm_fixup_ops(struct xsm_operations *ops);
>
>  #ifdef CONFIG_MULTIBOOT
>  static inline int xsm_multiboot_init (unsigned long *module_map,
> -                                      const multiboot_info_t *mbi,
> -                                      void *(*bootstrap_map)(const module_t *))
> +                                      const xbi_t *xbi,
> +                                      void *(*bootstrap_map)(const boot_module_t *))
>  {
>      return 0;
>  }
> diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
> index 0ac6d03..85d4d33 100644
> --- a/xen/xsm/xsm_core.c
> +++ b/xen/xsm/xsm_core.c
> @@ -60,8 +60,8 @@ static int __init xsm_core_init(void)
>
>  #ifdef CONFIG_MULTIBOOT
>  int __init xsm_multiboot_init(unsigned long *module_map,
> -                              const multiboot_info_t *mbi,
> -                              void *(*bootstrap_map)(const module_t *))
> +                              const xbi_t *xbi,
> +                              void *(*bootstrap_map)(const boot_module_t *))
>  {
>      int ret = 0;
>
> @@ -69,7 +69,7 @@ int __init xsm_multiboot_init(unsigned long *module_map,
>
>      if ( XSM_MAGIC )
>      {
> -        ret = xsm_multiboot_policy_init(module_map, mbi, bootstrap_map);
> +        ret = xsm_multiboot_policy_init(module_map, xbi, bootstrap_map);
>          if ( ret )
>          {
>              bootstrap_map(NULL);
> diff --git a/xen/xsm/xsm_policy.c b/xen/xsm/xsm_policy.c
> index 6e0bb78..5700eac 100644
> --- a/xen/xsm/xsm_policy.c
> +++ b/xen/xsm/xsm_policy.c
> @@ -19,9 +19,6 @@
>   */
>
>  #include <xsm/xsm.h>
> -#ifdef CONFIG_MULTIBOOT
> -#include <xen/multiboot.h>
> -#endif
>  #include <xen/bitops.h>
>  #ifdef HAS_DEVICE_TREE
>  # include <asm/setup.h>
> @@ -33,11 +30,10 @@ u32 __initdata policy_size = 0;
>
>  #ifdef CONFIG_MULTIBOOT
>  int __init xsm_multiboot_policy_init(unsigned long *module_map,
> -                                     const multiboot_info_t *mbi,
> -                                     void *(*bootstrap_map)(const module_t *))
> +                                     const xbi_t *xbi,
> +                                     void *(*bootstrap_map)(const boot_module_t *))
>  {
>      int i;
> -    module_t *mod = (module_t *)__va(mbi->mods_addr);
>      int rc = 0;
>      u32 *_policy_start;
>      unsigned long _policy_len;
> @@ -46,13 +42,13 @@ int __init xsm_multiboot_policy_init(unsigned long *module_map,
>       * Try all modules and see whichever could be the binary policy.
>       * Adjust module_map for the module that is the binary policy.
>       */
> -    for ( i = mbi->mods_count-1; i >= 1; i-- )
> +    for ( i = xbi->mods_nr - 1; i >= 1; i-- )
>      {
>          if ( !test_bit(i, module_map) )
>              continue;
>
> -        _policy_start = bootstrap_map(mod + i);
> -        _policy_len   = mod[i].mod_end;
> +        _policy_start = bootstrap_map(xbi->mods + i);
> +        _policy_len   = xbi->mods[i].end;
>
>          if ( (xsm_magic_t)(*_policy_start) == XSM_MAGIC )
>          {
> --
> 1.7.10.4
>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-09  0:07   ` Roy Franz
@ 2014-08-10 16:22     ` Daniel Kiper
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-10 16:22 UTC (permalink / raw)
  To: Roy Franz
  Cc: keir, Ian Campbell, Stefano Stabellini, ross.philipson, ning.sun,
	Jan Beulich, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, Fu Wei

On Fri, Aug 08, 2014 at 05:07:09PM -0700, Roy Franz wrote:
> On Fri, Aug 8, 2014 at 4:04 PM, Daniel Kiper <daniel.kiper@oracle.com> wrote:
> > We have all constants and structures in place. So, finally break multiboot (v1)
> > protocol dependency. It means that most of Xen code (excluding preloader)
> > could be bootloader agnostic and does not need almost any knowledge about
> > boot protocol. Additionally, we are able to pass all boot data to __start_xen()
> > in one bucket without any side channels. I do not mention that we are also
> > able to easily identify boot data in Xen code.
> >
> > Here is boot data flow for legacy BIOS platform:
> >
> >   BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
> >                                                         /
> >                      -----------------<-----------------
> >                      \
> >                       \
> >                        ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
> >                       /
> >              BIOS ->-/
> >
> >   * multiboot2 is not implemented yet. Look for it in next patch.
> >
> > Here is boot data flow for EFI platform:
> >
> >   EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI
> >
> > WARNING: ARM build could be broken by this patch. We need to agree XBI
> > integration into ARM. Personally I think that it is worth storing all
> > data from any bootloader and preloader in XBI on any architecture. This
> > give a chance to share more code between architectures. However, every
> > architecture should define its own XBI (in relevant include/asm directory).
> > Despite that it looks that some parts of it could be common, e.g.  modules
> > data, command line arguments, boot loader name, EFI data, etc., even if types
> > would not be the same. So, as it was stated above a lot of code could be
> > shared among architectures.
>
> From looking at this patch, it only conflicts slightly with the arm64 EFI work
> I have been doing.  Most of the changes are to areas of efi/boot.c that I don't
> touch.  From a practical point of view it should be relatively easy
> for me to base
> my patch series on yours or vice versa.

That is great! However, does it mean that we are able to share EFI runtime
related parts between ARM and x86 only? Is it not possible to do that
in regards to EFI boot related stuff? What is different?

> GRUB uses device tree to describe modules passed to XEN, so it's
> not clear to me what the advantage of translating a device tree description
> of modules into an ARM specific XBI structure would have.

I suppose that thanks to XBI we would be able to avoid patches like
commit 55862a9383fdefa41db8790d5e1379dffc97387d (xen/xsm: Don't use
multiboot by default to initialize XSM). This is one example. There are
more places where common Xen code touches multiboot variable (mbi) too.
This makes code sharing among architectures more difficult because you must
add #ifdef stuff in theoretically common files which is not nice. So, I
think that there are some gains which we could get from introducing XBI
as a common boot data holder.

Side note: I do not know ARM a lot so please correct me if I am wrong.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
@ 2014-08-10 16:34   ` Andrew Cooper
  2014-09-18 16:30     ` Daniel Kiper
  2014-08-11  9:54   ` Jan Beulich
  2014-08-11 16:20   ` Stefano Stabellini
  2 siblings, 1 reply; 40+ messages in thread
From: Andrew Cooper @ 2014-08-10 16:34 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 09/08/14 00:04, Daniel Kiper wrote:
> Define Xen Boot Info (XBI) type. This will be used to define variable
> used to store data collected by bootloader and preloader. This way
> we are able to make most of Xen code bootloader agnostic.
>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

This looks ok in principle, and the end goal seems like a good idea.

> ---
>  xen/include/asm-x86/xbi.h |  117 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 117 insertions(+)
>  create mode 100644 xen/include/asm-x86/xbi.h
>
> diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
> new file mode 100644
> index 0000000..ca9e615
> --- /dev/null
> +++ b/xen/include/asm-x86/xbi.h
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __XBI_H__
> +#define __XBI_H__
> +
> +#include <xen/types.h>
> +#include <xen/vga.h>
> +
> +#include <asm/e820.h>
> +#include <asm/edd.h>
> +#include <asm/mbd.h>
> +
> +/* Xen Boot Info (XBI) type. */

Probably need a rather larger comment here, reiterating that this
structure is a collection of information provided/found by the
bootloader/preloader, and presented in a common place for the Xen boot code.

> +typedef struct {
> +    /* Boot loader name. */
> +    char *boot_loader_name;
> +
> +    /* Xen command line. */
> +    char *cmdline;
> +
> +    /* Memory map type (source of memory map). */
> +    char *mmap_type;
> +
> +    /*
> +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> +     * Specification version 0.6.96.
> +     */
> +    u32 mem_upper;
> +
> +    /* Number of memory map entries provided by Xen preloader. */
> +    int e820map_nr;

Count of e820 entries is inherently an unsigned quantity.

> +
> +    /*
> +     * Memory map provided by Xen preloader. It should always point
> +     * to an area able to accommodate at least E820MAX entries.
> +     */
> +    struct e820entry *e820map;
> +
> +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
> +    unsigned long efi_mmap_size;
> +
> +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
> +    unsigned long efi_mmap_desc_size;

size_t for these two?

> +
> +    /* Pointer to EFI memory map provided by preloader. */
> +    void *efi_mmap;
> +
> +    /* Pointer to MPS. */
> +    unsigned long mps;
> +
> +    /* Pointer to ACPI RSDP. */
> +    unsigned long acpi;
> +
> +    /* Pointer to ACPI 2.0 RSDP. */
> +    unsigned long acpi20;
> +
> +    /* Pointer to SMBIOS. */
> +    unsigned long smbios;

I presume these 4 are all physical addresses?  how about paddr_t ?

> +
> +    /* Pointer to EFI System Table. */
> +    void *efi_system_table;
> +
> +    /* VGA console info. */
> +    struct xen_vga_console_info vga_console_info;
> +
> +    /* EDID info. */
> +    unsigned short edid_caps;
> +    unsigned char *edid_info;
> +
> +    /* Number of EDD entries provided by Xen preloader. */
> +    u8 edd_info_nr;
> +
> +    /* Pointer to EDD info. */
> +    struct edd_info *edd_info;
> +
> +    /* Number of MBR entries provided by Xen preloader. */
> +    u8 mbr_signature_nr;
> +
> +    /* Pointer to MBR info. */
> +    struct mbr_signature *mbr_signature;
> +
> +    /* Number of modules. */
> +    unsigned int mods_nr;
> +
> +    /* Pointer to modules description. */
> +    boot_module_t *mods;
> +
> +    /*
> +     * Info about warning occurred during XBI initialization.
> +     * NULL if everything went OK.
> +     */
> +    char *warn_msg;
> +
> +    /*
> +     * Info about error occurred during XBI initialization. NULL if everything
> +     * went OK. Otherwise XBI is not fully/properly initialized.
> +     */
> +    char *err_msg;
> +} xbi_t;
> +
> +extern xbi_t *xbi;

I realise this is very subjective, but I quite dislike this name.  The X
is redundant, this being the Xen source tree, and BI could perfectly
easily be an object called "boot_into", which would be rather clearer
when used in the code.

~Andrew

> +#endif /* __XBI_H__ */

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-08 23:04 ` [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper
  2014-08-09  0:07   ` Roy Franz
@ 2014-08-10 17:05   ` Andrew Cooper
  2014-08-11 10:01     ` Jan Beulich
  2014-09-09 13:22     ` Daniel Kiper
  1 sibling, 2 replies; 40+ messages in thread
From: Andrew Cooper @ 2014-08-10 17:05 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 09/08/14 00:04, Daniel Kiper wrote:
> We have all constants and structures in place. So, finally break multiboot (v1)
> protocol dependency. It means that most of Xen code (excluding preloader)
> could be bootloader agnostic and does not need almost any knowledge about
> boot protocol. Additionally, we are able to pass all boot data to __start_xen()
> in one bucket without any side channels. I do not mention that we are also
> able to easily identify boot data in Xen code.
>
> Here is boot data flow for legacy BIOS platform:
>
>   BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
>                                                         /
>                      -----------------<-----------------
>                      \
>                       \
>                        ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
>                       /
>              BIOS ->-/
>
>   * multiboot2 is not implemented yet. Look for it in next patch.
>
> Here is boot data flow for EFI platform:
>
>   EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI
>
> WARNING: ARM build could be broken by this patch. We need to agree XBI
> integration into ARM. Personally I think that it is worth storing all
> data from any bootloader and preloader in XBI on any architecture. This
> give a chance to share more code between architectures. However, every
> architecture should define its own XBI (in relevant include/asm directory).
> Despite that it looks that some parts of it could be common, e.g.  modules
> data, command line arguments, boot loader name, EFI data, etc., even if types
> would not be the same. So, as it was stated above a lot of code could be
> shared among architectures.
>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>

This patch is massive, and really needs splitting up somewhat.  There
are several logically distinct bits to it.

> ---
>  xen/arch/x86/Makefile             |    1 +
>  xen/arch/x86/boot/cmdline.S       |    9 +-
>  xen/arch/x86/boot/head.S          |   31 ++--
>  xen/arch/x86/boot/reloc.c         |  153 ++++++++++++-----
>  xen/arch/x86/boot/x86_64.S        |   10 +-
>  xen/arch/x86/dmi_scan.c           |    7 +-
>  xen/arch/x86/domain_build.c       |   24 +--
>  xen/arch/x86/efi/boot.c           |  212 +++++++++++------------
>  xen/arch/x86/efi/efi.h            |    3 -
>  xen/arch/x86/efi/runtime.c        |   52 ++++--
>  xen/arch/x86/init_xbi.c           |  254 +++++++++++++++++++++++++++
>  xen/arch/x86/microcode.c          |   39 ++---
>  xen/arch/x86/mpparse.c            |    9 +-
>  xen/arch/x86/platform_hypercall.c |   19 +--
>  xen/arch/x86/setup.c              |  340 +++++++++++--------------------------
>  xen/arch/x86/x86_64/asm-offsets.c |    5 +-
>  xen/drivers/acpi/osl.c            |    9 +-
>  xen/drivers/video/vesa.c          |    5 +-
>  xen/drivers/video/vga.c           |   16 +-
>  xen/include/asm-x86/config.h      |    2 -
>  xen/include/asm-x86/e820.h        |    8 -
>  xen/include/asm-x86/edd.h         |    6 -
>  xen/include/asm-x86/setup.h       |   10 +-
>  xen/include/xen/efi.h             |   10 --
>  xen/include/xen/vga.h             |    4 -
>  xen/include/xsm/xsm.h             |   14 +-
>  xen/xsm/xsm_core.c                |    6 +-
>  xen/xsm/xsm_policy.c              |   14 +-
>  28 files changed, 723 insertions(+), 549 deletions(-)
>  create mode 100644 xen/arch/x86/init_xbi.c
>
> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> index c1e244d..bb2264a 100644
> --- a/xen/arch/x86/Makefile
> +++ b/xen/arch/x86/Makefile
> @@ -42,6 +42,7 @@ obj-y += numa.o
>  obj-y += pci.o
>  obj-y += percpu.o
>  obj-y += physdev.o
> +obj-y += init_xbi.o

init_xbi is not a fantastic filename.  xbi alone would be better
(subject to my concerned about the name xbi).

>  obj-y += setup.o
>  obj-y += shutdown.o
>  obj-y += smp.o
> diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
> index 00687eb..7316011 100644
> --- a/xen/arch/x86/boot/cmdline.S
> +++ b/xen/arch/x86/boot/cmdline.S
> @@ -152,17 +152,14 @@ cmdline_parse_early:
>          pusha
>  
>          /* Bail if there is no command line to parse. */
> -        mov     sym_phys(multiboot_ptr),%ebx
> -        mov     MB_flags(%ebx),%eax
> -        test    $4,%al
> -        jz      .Lcmdline_exit
> -        mov     MB_cmdline(%ebx),%eax
> +        mov     sym_phys(mbd_ptr),%ebx
> +        mov     MBD_cmdline(%ebx),%eax

FLAGS & MBI_CMDLINE is the prerequisite for the 'cmdline' field being
valid.  You cannot drop that check (although making use of some manifest
constants would help)

>          test    %eax,%eax
>          jz      .Lcmdline_exit
>  
>          /* Check for 'no-real-mode' command-line option. */
>          pushl   $sym_phys(.Lno_rm_opt)
> -        pushl   MB_cmdline(%ebx)
> +        pushl   MBD_cmdline(%ebx)
>          call    .Lfind_option
>          test    %eax,%eax
>          setnz   %al
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 10ecf51..79bce3c 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -86,14 +86,14 @@ __start:
>          jne     not_multiboot
>  
>          /* Set up trampoline segment 64k below EBDA */
> -        movzwl  0x40e,%eax          /* EBDA segment */
> -        cmp     $0xa000,%eax        /* sanity check (high) */
> +        movzwl  0x40e,%ecx          /* EBDA segment */
> +        cmp     $0xa000,%ecx        /* sanity check (high) */
>          jae     0f
> -        cmp     $0x4000,%eax        /* sanity check (low) */
> +        cmp     $0x4000,%ecx        /* sanity check (low) */
>          jae     1f
>  0:
> -        movzwl  0x413,%eax          /* use base memory size on failure */
> -        shl     $10-4,%eax
> +        movzwl  0x413,%ecx          /* use base memory size on failure */
> +        shl     $10-4,%ecx
>  1:
>          /*
>           * Compare the value in the BDA with the information from the
> @@ -105,22 +105,23 @@ __start:
>          cmp     $0x100,%edx         /* is the multiboot value too small? */
>          jb      2f                  /* if so, do not use it */
>          shl     $10-4,%edx
> -        cmp     %eax,%edx           /* compare with BDA value */
> -        cmovb   %edx,%eax           /* and use the smaller */
> +        cmp     %ecx,%edx           /* compare with BDA value */
> +        cmovb   %edx,%ecx           /* and use the smaller */
>  
>  2:      /* Reserve 64kb for the trampoline */
> -        sub     $0x1000,%eax
> +        sub     $0x1000,%ecx
>  
>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
> -        xor     %al, %al
> -        shl     $4, %eax
> -        mov     %eax,sym_phys(trampoline_phys)
> +        xor     %cl, %cl
> +        shl     $4, %ecx
> +        mov     %ecx,sym_phys(trampoline_phys)
>  
> -        /* Save the Multiboot info struct (after relocation) for later use. */
> +        /* Save the Multiboot data (after relocation) for later use. */
>          mov     $sym_phys(cpu0_stack)+1024,%esp
> -        push    %ebx
> -        call    reloc
> -        mov     %eax,sym_phys(multiboot_ptr)
> +        push    %eax                /* Multiboot magic */
> +        push    %ebx                /* Multiboot information address */
> +        call    reloc               /* %ecx contains trampoline address */
> +        mov     %eax,sym_phys(mbd_ptr)
>  
>          /* Initialize BSS (no nasty surprises!) */
>          mov     $sym_phys(__bss_start),%edi
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index fa0fb6b..29f4887 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -1,40 +1,56 @@
> -/******************************************************************************
> +/*
>   * reloc.c
> - * 
> + *
>   * 32-bit flat memory-map routines for relocating Multiboot structures
>   * and modules. This is most easily done early with paging disabled.
> - * 
> + *
>   * Copyright (c) 2009, Citrix Systems, Inc.
> - * 
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
>   * Authors:
>   *    Keir Fraser <keir@xen.org>
> + *    Daniel Kiper
>   */
>  
> -/* entered with %eax = BOOT_TRAMPOLINE */
> +typedef unsigned char u8;
> +typedef unsigned short u16;
> +typedef unsigned long u32;
> +typedef unsigned long long u64;
> +
> +#include "../../../include/xen/multiboot.h"
> +#include "../../../include/asm/mbd.h"
> +
> +/*
> + * __HERE__ IS TRUE ENTRY POINT!!!
> + *
> + * It is entered from xen/arch/x86/boot/head.S with:
> + *   - %eax = MULTIBOOT_MAGIC,
> + *   - %ebx = MULTIBOOT_INFORMATION_ADDRESS,
> + *   - %ecx = BOOT_TRAMPOLINE.
> + */
>  asm (
>      "    .text                         \n"
>      "    .globl _start                 \n"
>      "_start:                           \n"
>      "    call 1f                       \n"
>      "1:  pop  %ebx                     \n"
> -    "    mov  %eax,alloc-1b(%ebx)      \n"
> -    "    jmp  reloc                    \n"
> +    "    mov  %ecx,alloc-1b(%ebx)      \n"
> +    "    jmp  __reloc                  \n"
>      );
>  
> -/* This is our data.  Because the code must be relocatable, no BSS is
> - * allowed.  All data is accessed PC-relative with inline assembly.
> +/*
> + * This is our data. Because the code must be relocatable, no BSS is
> + * allowed. All data is accessed PC-relative with inline assembly.
>   */
>  asm (
>      "alloc:                            \n"
>      "    .long 0                       \n"
>      );
>  
> -typedef unsigned int u32;
> -#include "../../../include/xen/multiboot.h"
> -
> -static void *reloc_mbi_struct(void *old, unsigned int bytes)
> +static u32 alloc_struct(u32 bytes)
>  {
> -    void *new;
> +    u32 s;
> +
>      asm(
>      "    call 1f                      \n"
>      "1:  pop  %%edx                   \n"
> @@ -42,58 +58,105 @@ static void *reloc_mbi_struct(void *old, unsigned int bytes)
>      "    sub  %1,%0                   \n"
>      "    and  $~15,%0                 \n"
>      "    mov  %0,alloc-1b(%%edx)      \n"
> -    "    mov  %0,%%edi                \n"
> +       : "=&r" (s) : "r" (bytes) : "edx");
> +
> +    return s;
> +}
> +
> +static void zero_struct(u32 s, u32 bytes)
> +{
> +    asm volatile(
> +    "    cld                          \n"

__start has already performed cld for us.  There is nothing which will
have set it between then and here.

> +    "    xor  %%eax,%%eax             \n"
> +    "    rep  stosb                   \n"
> +       : "+D" (s), "+c" (bytes) : : "eax");

Why not "a" (0) and drop the xor and eax clobber?

> +}
> +
> +static u32 copy_struct(u32 src, u32 bytes)
> +{
> +    u32 dst;
> +
> +    dst = alloc_struct(bytes);
> +
> +    asm volatile(
> +    "    cld                          \n"
> +    "    mov  %2,%%edi                \n"
>      "    rep  movsb                   \n"
> -       : "=&r" (new), "+c" (bytes), "+S" (old)
> -	: : "edx", "edi");
> -    return new;
> +       : "+S" (src), "+c" (bytes) : "r" (dst) : "edi");

Again, drop the mov %2,%%edi and use proper parameters without clobbers

> +
> +    return dst;
>  }
>  
> -static char *reloc_mbi_string(char *old)
> +static u32 copy_string(u32 src)
>  {
>      char *p;
> -    for ( p = old; *p != '\0'; p++ )
> +
> +    if ( src == 0 )
> +        return 0;
> +
> +    for ( p = (char *)src; *p != '\0'; p++ )
>          continue;
> -    return reloc_mbi_struct(old, p - old + 1);
> +
> +    return copy_struct(src, p - (char *)src + 1);
>  }
>  
> -multiboot_info_t *reloc(multiboot_info_t *mbi_old)
> +static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
>  {
> -    multiboot_info_t *mbi = reloc_mbi_struct(mbi_old, sizeof(*mbi));
>      int i;
> +    module_t *mbi_mods;
> +    boot_module_t *mbd_mods;
> +
> +    if ( mbi->flags & MBI_LOADERNAME )
> +        mbd->boot_loader_name = copy_string(mbi->boot_loader_name);
>  
>      if ( mbi->flags & MBI_CMDLINE )
> -        mbi->cmdline = (u32)reloc_mbi_string((char *)mbi->cmdline);
> +        mbd->cmdline = copy_string(mbi->cmdline);
> +
> +    if ( mbi->flags & MBI_MEMLIMITS )
> +    {
> +        mbd->mem_lower = mbi->mem_lower;
> +        mbd->mem_upper = mbi->mem_upper;
> +    }
> +
> +    if ( mbi->flags & MBI_MEMMAP )
> +    {
> +        mbd->mmap_size = mbi->mmap_length;
> +        mbd->mmap = copy_struct(mbi->mmap_addr, mbi->mmap_length);
> +    }
>  
>      if ( mbi->flags & MBI_MODULES )
>      {
> -        module_t *mods = reloc_mbi_struct(
> -            (module_t *)mbi->mods_addr, mbi->mods_count * sizeof(module_t));
> +        mbd->mods_nr = mbi->mods_count;
> +        mbd->mods = alloc_struct(mbi->mods_count * sizeof(boot_module_t));
>  
> -        mbi->mods_addr = (u32)mods;
> +        mbi_mods = (module_t *)mbi->mods_addr;
> +        mbd_mods = (boot_module_t *)mbd->mods;
>  
>          for ( i = 0; i < mbi->mods_count; i++ )
>          {
> -            if ( mods[i].string )
> -                mods[i].string = (u32)reloc_mbi_string((char *)mods[i].string);
> +            mbd_mods[i].start = mbi_mods[i].mod_start;
> +            mbd_mods[i].end = mbi_mods[i].mod_end;
> +            mbd_mods[i].cmdline = copy_string(mbi_mods[i].string);
> +            mbd_mods[i].relocated = 0;
>          }
>      }
>  
> -    if ( mbi->flags & MBI_MEMMAP )
> -        mbi->mmap_addr = (u32)reloc_mbi_struct(
> -            (memory_map_t *)mbi->mmap_addr, mbi->mmap_length);
> +    return mbd;
> +}
>  
> -    if ( mbi->flags & MBI_LOADERNAME )
> -        mbi->boot_loader_name = (u32)reloc_mbi_string(
> -            (char *)mbi->boot_loader_name);
> -
> -    /* Mask features we don't understand or don't relocate. */
> -    mbi->flags &= (MBI_MEMLIMITS |
> -                   MBI_BOOTDEV |
> -                   MBI_CMDLINE |
> -                   MBI_MODULES |
> -                   MBI_MEMMAP |
> -                   MBI_LOADERNAME);
> -
> -    return mbi;
> +/*
> + * __THIS__ IS NOT ENTRY POINT!!!
> + * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!

I don't think this needs stating...

> + *
> + * It could be a static but then compiler complains:
> + * error: ‘__reloc’ defined but not used.
> + */
> +mbd_t *__reloc(void *mbi, u32 mb_magic)

static mbd_t *__reloc(void *mbi, u32 mb_magic) __attribute__((used)) is
the correct way of informing gcc that it is referenced from inline assembly.

> +{
> +    mbd_t *mbd;
> +
> +    mbd = (mbd_t *)alloc_struct(sizeof(mbd_t));
> +    zero_struct((u32)mbd, sizeof(mbd_t));
> +
> +    return mb_mbd(mbd, mbi);
>  }
> diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
> index bfbafd2..ec39d38 100644
> --- a/xen/arch/x86/boot/x86_64.S
> +++ b/xen/arch/x86/boot/x86_64.S
> @@ -29,8 +29,12 @@
>          test    %ebx,%ebx
>          jnz     start_secondary
>  
> -        /* Pass off the Multiboot info structure to C land. */
> -        mov     multiboot_ptr(%rip),%edi
> +        /* Init Xen Boot Info. */
> +        mov     mbd_ptr(%rip),%edi
> +        call    __init_xbi

This is a large quantity of code shuffling bits of data, which does not
strictly need to be done at this point.

Please defer it until after full trap support has been set up in
__start_xen().

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-08-08 23:04 ` [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support Daniel Kiper
@ 2014-08-10 17:23   ` Andrew Cooper
  2014-09-09 13:34     ` Daniel Kiper
  2014-08-11 10:33   ` Jan Beulich
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Cooper @ 2014-08-10 17:23 UTC (permalink / raw)
  To: Daniel Kiper, xen-devel
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On 09/08/14 00:04, Daniel Kiper wrote:
> Add multiboot2 protocol support. This way we are laying the foundation
> for EFI + GRUB2 + Xen development.
>
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/arch/x86/boot/head.S  |  112 ++++++++++++++++++++++++++++++++++++++++++++-
>  xen/arch/x86/boot/reloc.c |  103 ++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 212 insertions(+), 3 deletions(-)
>
> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> index 79bce3c..f0ea6d0 100644
> --- a/xen/arch/x86/boot/head.S
> +++ b/xen/arch/x86/boot/head.S
> @@ -1,5 +1,6 @@
>  #include <xen/config.h>
>  #include <xen/multiboot.h>
> +#include <xen/multiboot2.h>
>  #include <public/xen.h>
>  #include <asm/asm_defns.h>
>  #include <asm/desc.h>
> @@ -33,6 +34,68 @@ ENTRY(start)
>          /* Checksum: must be the negated sum of the first two fields. */
>          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
>  
> +/*** MULTIBOOT2 HEADER ****/
> +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
> +        .align  MULTIBOOT2_HEADER_ALIGN
> +
> +multiboot2_header:
> +        /* Magic number indicating a Multiboot2 header. */
> +        .long   MULTIBOOT2_HEADER_MAGIC
> +        /* Architecture: i386. */
> +        .long   MULTIBOOT2_ARCHITECTURE_I386
> +        /* Multiboot2 header length. */
> +        .long   multiboot2_header_end - multiboot2_header
> +        /* Multiboot2 header checksum. */
> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> +                        (multiboot2_header_end - multiboot2_header))
> +
> +        /* Multiboot2 tags... */
> +multiboot2_info_req:
> +        /* Multiboot2 information request tag. */
> +        .short  MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST
> +        .short  MULTIBOOT2_HEADER_TAG_REQUIRED
> +        .long   multiboot2_info_req_end - multiboot2_info_req
> +        .long   MULTIBOOT2_TAG_TYPE_MMAP
> +multiboot2_info_req_end:
> +
> +        /*
> +         * Align Xen image and modules at page boundry.
> +         *
> +         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
> +         * to avoid bug related to Multiboot2 information request tag in earlier
> +         * versions of GRUB2.
> +         *
> +         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
> +         * WITH EARLIER GRUB2 VERSIONS!
> +         */
> +        .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END
> +        .short   MULTIBOOT2_HEADER_TAG_MODULE_ALIGN
> +        .short   MULTIBOOT2_HEADER_TAG_REQUIRED
> +        .long    8 /* Tag size. */
> +
> +        /* Console flags tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS
> +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +        .long   12 /* Tag size. */
> +        .long   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> +
> +        /* Framebuffer tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_FRAMEBUFFER
> +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +        .long   20 /* Tag size. */
> +        .long   0 /* Number of the columns - no preference. */
> +        .long   0 /* Number of the lines - no preference. */
> +        .long   0 /* Number of bits per pixel - no preference. */
> +
> +        /* Multiboot2 header end tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_END
> +        .short  0
> +        .long   8 /* Tag size. */
> +multiboot2_header_end:
> +
>          .section .init.rodata, "a", @progbits
>          .align 4
>  
> @@ -81,10 +144,55 @@ __start:
>          mov     %ecx,%es
>          mov     %ecx,%ss
>  
> +        /* Set mem_lower to 0 */
> +        xor     %edx,%edx
> +

How does this affect mem_lower? it doesn't appear relevant in context.

>          /* Check for Multiboot bootloader */
> -        cmp     $0x2BADB002,%eax
> -        jne     not_multiboot
> +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> +        je      1f

This $MULTIBOOT_BOOTLOADER_MAGIC should probably be separate, as there
are other bits of code which should use multiboot manifest constants.

It looks as if this should be "je multiboot1_entry" ...

> +
> +        /* Check for Multiboot2 bootloader */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      2f
> +
> +        jmp     not_multiboot
> +
> +1:
> +        /* Get mem_lower from Multiboot information */
> +        testb   $MBI_MEMLIMITS,(%ebx)
> +        jz      0f                  /* not available? BDA value will be fine */
>  
> +        mov     4(%ebx),%edx
> +        shl     $10-4,%edx
> +        jmp     0f

and these 0f's should be "setup_trampoline" or similar.  You have also
removed some sanity checks of the multiboot information, which need
reintroducing.

> +
> +2:

This 2 should be "multiboot2_entry"

> +        /* Get Multiboot2 information address */
> +        mov     %ebx,%ecx
> +        add     $8,%ecx

Any manifest constants for this, or at least a reference to some
documentation describing how the tags are laid out?

> +
> +3:
> +        /* Get mem_lower from Multiboot2 information */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> +        jne     4f
> +
> +        mov     8(%ecx),%edx
> +        shl     $10-4,%edx
> +        jmp     5f

BASIC_MEMINFO is the only tag we look for.  No need to spin through all
of them if we found it.  Also, needs the same sanity checking as the
multiboot1 information.

~Andrew

> +
> +4:
> +        /* Is it the end of Multiboot2 information? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_END,(%ecx)
> +        je      0f
> +
> +5:
> +        /* Go to next Multiboot2 information tag */
> +        add     4(%ecx),%ecx
> +        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        jmp     3b
> +
> +0:
>          /* Set up trampoline segment 64k below EBDA */
>          movzwl  0x40e,%ecx          /* EBDA segment */
>          cmp     $0xa000,%ecx        /* sanity check (high) */
> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> index 29f4887..eaf3226 100644
> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -18,8 +18,12 @@ typedef unsigned long u32;
>  typedef unsigned long long u64;
>  
>  #include "../../../include/xen/multiboot.h"
> +#include "../../../include/xen/multiboot2.h"
>  #include "../../../include/asm/mbd.h"
>  
> +#define ALIGN_UP(addr, align) \
> +                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align - 1))
> +
>  /*
>   * __HERE__ IS TRUE ENTRY POINT!!!
>   *
> @@ -144,6 +148,100 @@ static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
>      return mbd;
>  }
>  
> +static mbd_t *mb2_mbd(mbd_t *mbd, void *mbi)
> +{
> +    int i, mod_idx = 0;
> +    memory_map_t *mmap_dst;
> +    multiboot2_memory_map_t *mmap_src;
> +    multiboot2_tag_t *tag;
> +    u32 ptr;
> +    boot_module_t *mbd_mods;
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi + sizeof(u32) * 2;
> +
> +    while ( 1 )
> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> +            ++mbd->mods_nr;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> +        {
> +            mbd->mods = alloc_struct(mbd->mods_nr * sizeof(boot_module_t));
> +            mbd_mods = (boot_module_t *)mbd->mods;
> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +    }
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi + sizeof(u32) * 2;
> +
> +    while ( 1 )
> +    {
> +        switch ( tag->type )
> +        {
> +        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
> +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> +            mbd->boot_loader_name = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_CMDLINE:
> +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> +            mbd->cmdline = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
> +            mbd->mem_lower = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_lower;
> +            mbd->mem_upper = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_upper;
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MMAP:
> +            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
> +            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
> +            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
> +            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
> +            mbd->mmap_size *= sizeof(memory_map_t);
> +
> +            mbd->mmap = alloc_struct(mbd->mmap_size);
> +
> +            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
> +            mmap_dst = (memory_map_t *)mbd->mmap;
> +
> +            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)
> +            {
> +                mmap_dst[i].size = sizeof(memory_map_t);
> +                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
> +                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
> +                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
> +                mmap_dst[i].length_low = (u32)mmap_src[i].len;
> +                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
> +                mmap_dst[i].type = mmap_src[i].type;
> +            }
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MODULE:
> +            mbd_mods[mod_idx].start = (u32)((multiboot2_tag_module_t *)tag)->mod_start;
> +            mbd_mods[mod_idx].end = (u32)((multiboot2_tag_module_t *)tag)->mod_end;
> +            ptr = (u32)((multiboot2_tag_module_t *)tag)->cmdline;
> +            mbd_mods[mod_idx].cmdline = copy_string(ptr);
> +            mbd_mods[mod_idx].relocated = 0;
> +            ++mod_idx;
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_END:
> +            return mbd;
> +
> +        default:
> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +    }
> +}
> +
>  /*
>   * __THIS__ IS NOT ENTRY POINT!!!
>   * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
> @@ -158,5 +256,8 @@ mbd_t *__reloc(void *mbi, u32 mb_magic)
>      mbd = (mbd_t *)alloc_struct(sizeof(mbd_t));
>      zero_struct((u32)mbd, sizeof(mbd_t));
>  
> -    return mb_mbd(mbd, mbi);
> +    if ( mb_magic == MULTIBOOT_BOOTLOADER_MAGIC )
> +        return mb_mbd(mbd, mbi);
> +    else
> +        return mb2_mbd(mbd, mbi);
>  }

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-08-08 23:04 ` [PATCH RFC 1/7] xen/x86: Add mbd.h header file Daniel Kiper
@ 2014-08-11  9:49   ` Jan Beulich
  2014-08-11 16:16     ` Stefano Stabellini
  2014-09-09 13:39     ` Daniel Kiper
  0 siblings, 2 replies; 40+ messages in thread
From: Jan Beulich @ 2014-08-11  9:49 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> --- /dev/null
> +++ b/xen/include/asm-x86/mbd.h
> @@ -0,0 +1,70 @@
> +/*
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __MBD_H__
> +#define __MBD_H__
> +
> +/* Module type. */
> +typedef struct {
> +    u32 start;
> +    u32 end;
> +
> +    /* Pointer to a module command line. */
> +    u32 cmdline;
> +
> +    /* If relocated != 0 then a given module was relocated. */
> +    u32 relocated;
> +} boot_module_t;
> +
> +/*
> + * MultiBoot Data (MBD) type. It is used to define variable which
> + * carry over data from multiboot protocol (any version) through
> + * Xen preloader stage. Later all or parts of this data is used
> + * to initialize Xen Boot Info (XBI) structure.
> + */
> +typedef struct {
> +    /* Pointer to boot loader name. */
> +    u32 boot_loader_name;
> +
> +    /* Pointer to Xen command line. */
> +    u32 cmdline;
> +
> +    /*
> +     * Amount of lower memory (in KiB) accordingly to The Multiboot
> +     * Specification version 0.6.96.
> +     */
> +    u32 mem_lower;
> +
> +    /*
> +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> +     * Specification version 0.6.96.
> +     */
> +    u32 mem_upper;
> +
> +    /* Size (in bytes) of memory map provided by bootloader. */
> +    u32 mmap_size;
> +
> +    /* Pointer to memory map provided by bootloader. */
> +    u32 mmap;
> +
> +    /* Number of modules. */
> +    u32 mods_nr;
> +
> +    /* Pointer to modules description (boot_module_t *). */
> +    u32 mods;
> +} mbd_t;
> +#endif /* __MBD_H__ */

For several of the fields I wonder whether u32 is really the right
data type (i.e. whether u64 wouldn't be more correct going
forward).

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
  2014-08-10 16:34   ` Andrew Cooper
@ 2014-08-11  9:54   ` Jan Beulich
  2014-08-11 16:20   ` Stefano Stabellini
  2 siblings, 0 replies; 40+ messages in thread
From: Jan Beulich @ 2014-08-11  9:54 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> +/* Xen Boot Info (XBI) type. */
> +typedef struct {
> +    /* Boot loader name. */
> +    char *boot_loader_name;
> +
> +    /* Xen command line. */
> +    char *cmdline;
> +
> +    /* Memory map type (source of memory map). */
> +    char *mmap_type;
> +
> +    /*
> +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> +     * Specification version 0.6.96.
> +     */
> +    u32 mem_upper;
> +
> +    /* Number of memory map entries provided by Xen preloader. */
> +    int e820map_nr;
> +
> +    /*
> +     * Memory map provided by Xen preloader. It should always point
> +     * to an area able to accommodate at least E820MAX entries.
> +     */
> +    struct e820entry *e820map;
> +
> +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
> +    unsigned long efi_mmap_size;
> +
> +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
> +    unsigned long efi_mmap_desc_size;
> +
> +    /* Pointer to EFI memory map provided by preloader. */
> +    void *efi_mmap;
> +
> +    /* Pointer to MPS. */
> +    unsigned long mps;
> +
> +    /* Pointer to ACPI RSDP. */
> +    unsigned long acpi;
> +
> +    /* Pointer to ACPI 2.0 RSDP. */
> +    unsigned long acpi20;
> +
> +    /* Pointer to SMBIOS. */
> +    unsigned long smbios;
> +
> +    /* Pointer to EFI System Table. */
> +    void *efi_system_table;
> +
> +    /* VGA console info. */
> +    struct xen_vga_console_info vga_console_info;
> +
> +    /* EDID info. */
> +    unsigned short edid_caps;
> +    unsigned char *edid_info;
> +
> +    /* Number of EDD entries provided by Xen preloader. */
> +    u8 edd_info_nr;
> +
> +    /* Pointer to EDD info. */
> +    struct edd_info *edd_info;
> +
> +    /* Number of MBR entries provided by Xen preloader. */
> +    u8 mbr_signature_nr;
> +
> +    /* Pointer to MBR info. */
> +    struct mbr_signature *mbr_signature;
> +
> +    /* Number of modules. */
> +    unsigned int mods_nr;
> +
> +    /* Pointer to modules description. */
> +    boot_module_t *mods;

Up to here I merely wonder whether some fields shouldn't rather be put
in unions; it's quite hard to tell though with just a header in a patch,
without any code using it.

> +
> +    /*
> +     * Info about warning occurred during XBI initialization.
> +     * NULL if everything went OK.
> +     */
> +    char *warn_msg;

Certainly there could be more than one warning. Perhaps these need
a linked list?

> +
> +    /*
> +     * Info about error occurred during XBI initialization. NULL if everything
> +     * went OK. Otherwise XBI is not fully/properly initialized.
> +     */
> +    char *err_msg;

Depending on whether such errors are fatal, there might (if they're
not) also be the possibility for more than one.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 3/7] xen: Add multiboot2.h header file
  2014-08-08 23:04 ` [PATCH RFC 3/7] xen: Add multiboot2.h " Daniel Kiper
@ 2014-08-11  9:58   ` Jan Beulich
  2014-09-09 13:47     ` Daniel Kiper
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Beulich @ 2014-08-11  9:58 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> --- /dev/null
> +++ b/xen/include/xen/multiboot2.h

I have to admit that I can't see why this can't all go into
xen/include/xen/multiboot.h - the two sets of definitions have to be
able to coexist anyway.

> +#ifndef __ASSEMBLY__
> +typedef struct
> +{

These opening braces should all go on the same line as the "struct"
keyword.

> +} multiboot2_tag_efi_mmap_t;
> +#endif /* __ASSEMBLY__ */
> +#endif /* __MULTIBOOT2_H__ */

Blank lines needed between at least the last two lines.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-10 17:05   ` Andrew Cooper
@ 2014-08-11 10:01     ` Jan Beulich
  2014-09-09 13:22     ` Daniel Kiper
  1 sibling, 0 replies; 40+ messages in thread
From: Jan Beulich @ 2014-08-11 10:01 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel, Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, qiaowei.ren, richard.l.maliszewski, gang.wei,
	fu.wei

>>> On 10.08.14 at 19:05, <andrew.cooper3@citrix.com> wrote:
> This patch is massive, and really needs splitting up somewhat.  There
> are several logically distinct bits to it.

+1 - I think I'll not even spend much time looking at the patch without
it being split up. The splitting is being done quite inconsistently anyway:
The first 3 patches were headers without users, and now we get this
extremely massive single patch.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-08-08 23:04 ` [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support Daniel Kiper
  2014-08-10 17:23   ` Andrew Cooper
@ 2014-08-11 10:33   ` Jan Beulich
  2014-09-09 14:21     ` Daniel Kiper
  1 sibling, 1 reply; 40+ messages in thread
From: Jan Beulich @ 2014-08-11 10:33 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> @@ -33,6 +34,68 @@ ENTRY(start)
>          /* Checksum: must be the negated sum of the first two fields. */
>          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
>  
> +/*** MULTIBOOT2 HEADER ****/
> +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
> +        .align  MULTIBOOT2_HEADER_ALIGN
> +
> +multiboot2_header:

While I'm fine with this label, ...

> +        /* Magic number indicating a Multiboot2 header. */
> +        .long   MULTIBOOT2_HEADER_MAGIC
> +        /* Architecture: i386. */
> +        .long   MULTIBOOT2_ARCHITECTURE_I386
> +        /* Multiboot2 header length. */
> +        .long   multiboot2_header_end - multiboot2_header
> +        /* Multiboot2 header checksum. */
> +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> +                        (multiboot2_header_end - multiboot2_header))
> +
> +        /* Multiboot2 tags... */
> +multiboot2_info_req:

... this and ...

> +        /* Multiboot2 information request tag. */
> +        .short  MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST
> +        .short  MULTIBOOT2_HEADER_TAG_REQUIRED
> +        .long   multiboot2_info_req_end - multiboot2_info_req
> +        .long   MULTIBOOT2_TAG_TYPE_MMAP
> +multiboot2_info_req_end:

... this are purely auxiliary and as such shouldn't end up in the
symbol table. Please prefix such labels with ".L".

> +
> +        /*
> +         * Align Xen image and modules at page boundry.
> +         *
> +         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
> +         * to avoid bug related to Multiboot2 information request tag in earlier
> +         * versions of GRUB2.
> +         *
> +         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
> +         * WITH EARLIER GRUB2 VERSIONS!
> +         */

Question is - since your ultimate goal of getting UEFI to work this way
won't be achievable with older GrUB2 anyway, do we care at all? Also,
at least a reasonable hint towards the nature of the referenced bug
should be added here, as in the end it's not too unlikely for there to
be more than one bug in an area like this. I.e. future people reading
this or working on the code should have a handle to decide whether
the hack is still applicable without first having to guess which specific
bug this is about.

> +        .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END
> +        .short   MULTIBOOT2_HEADER_TAG_MODULE_ALIGN
> +        .short   MULTIBOOT2_HEADER_TAG_REQUIRED

Readability would certainly benefit if you macro-ized the tag
generation, at least to avoid the many redundant
MULTIBOOT2_HEADER_TAG_ prefixes (but perhaps also the
alignment).

> +        .long    8 /* Tag size. */
> +
> +        /* Console flags tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS
> +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +        .long   12 /* Tag size. */
> +        .long   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> +
> +        /* Framebuffer tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_FRAMEBUFFER
> +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> +        .long   20 /* Tag size. */
> +        .long   0 /* Number of the columns - no preference. */
> +        .long   0 /* Number of the lines - no preference. */
> +        .long   0 /* Number of bits per pixel - no preference. */
> +
> +        /* Multiboot2 header end tag. */
> +        .align  MULTIBOOT2_TAG_ALIGN
> +        .short  MULTIBOOT2_HEADER_TAG_END
> +        .short  0
> +        .long   8 /* Tag size. */
> +multiboot2_header_end:
> +
>          .section .init.rodata, "a", @progbits
>          .align 4
>  
> @@ -81,10 +144,55 @@ __start:
>          mov     %ecx,%es
>          mov     %ecx,%ss
>  
> +        /* Set mem_lower to 0 */
> +        xor     %edx,%edx
> +
>          /* Check for Multiboot bootloader */
> -        cmp     $0x2BADB002,%eax
> -        jne     not_multiboot
> +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> +        je      1f
> +
> +        /* Check for Multiboot2 bootloader */
> +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> +        je      2f
> +
> +        jmp     not_multiboot
> +
> +1:
> +        /* Get mem_lower from Multiboot information */
> +        testb   $MBI_MEMLIMITS,(%ebx)
> +        jz      0f                  /* not available? BDA value will be fine */
>  
> +        mov     4(%ebx),%edx
> +        shl     $10-4,%edx
> +        jmp     0f

This code isn't being moved here from elsewhere, but also isn't
multiboot2 related - what's this about? If it's really needed for
something, this should be in a separate patch imo.

> +
> +2:
> +        /* Get Multiboot2 information address */
> +        mov     %ebx,%ecx
> +        add     $8,%ecx
> +
> +3:
> +        /* Get mem_lower from Multiboot2 information */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> +        jne     4f
> +
> +        mov     8(%ecx),%edx
> +        shl     $10-4,%edx
> +        jmp     5f
> +
> +4:
> +        /* Is it the end of Multiboot2 information? */
> +        cmpl    $MULTIBOOT2_TAG_TYPE_END,(%ecx)
> +        je      0f
> +
> +5:
> +        /* Go to next Multiboot2 information tag */
> +        add     4(%ecx),%ecx
> +        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> +        jmp     3b
> +
> +0:

Please consider giving some or all, but at the very least the last,
labels descriptive names instead of just using numeric ones.

> --- a/xen/arch/x86/boot/reloc.c
> +++ b/xen/arch/x86/boot/reloc.c
> @@ -18,8 +18,12 @@ typedef unsigned long u32;
>  typedef unsigned long long u64;
>  
>  #include "../../../include/xen/multiboot.h"
> +#include "../../../include/xen/multiboot2.h"
>  #include "../../../include/asm/mbd.h"
>  
> +#define ALIGN_UP(addr, align) \
> +                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align - 1))

Even if just used locally, please make sure such macros are properly
parenthesized.

> @@ -144,6 +148,100 @@ static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
>      return mbd;
>  }
>  
> +static mbd_t *mb2_mbd(mbd_t *mbd, void *mbi)
> +{
> +    int i, mod_idx = 0;

unsigned for both afaict.

> +    memory_map_t *mmap_dst;
> +    multiboot2_memory_map_t *mmap_src;
> +    multiboot2_tag_t *tag;
> +    u32 ptr;
> +    boot_module_t *mbd_mods;
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi + sizeof(u32) * 2;

Is there no way to properly express this via e.g. an offsetof()?

> +
> +    while ( 1 )

To avoid "condition is constant warnings" on certain compilers, I'd
recommend using for ( ; ; ) instead of while ( 1 ).

> +    {
> +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> +            ++mbd->mods_nr;
> +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> +        {
> +            mbd->mods = alloc_struct(mbd->mods_nr * sizeof(boot_module_t));
> +            mbd_mods = (boot_module_t *)mbd->mods;
> +            break;
> +        }
> +
> +        /* Go to next Multiboot2 information tag. */
> +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> +    }
> +
> +    /* Skip Multiboot2 information fixed part. */
> +    tag = mbi + sizeof(u32) * 2;
> +
> +    while ( 1 )
> +    {
> +        switch ( tag->type )
> +        {
> +        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
> +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> +            mbd->boot_loader_name = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_CMDLINE:
> +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> +            mbd->cmdline = copy_string(ptr);
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
> +            mbd->mem_lower = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_lower;
> +            mbd->mem_upper = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_upper;
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MMAP:
> +            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
> +            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
> +            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
> +            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
> +            mbd->mmap_size *= sizeof(memory_map_t);
> +
> +            mbd->mmap = alloc_struct(mbd->mmap_size);
> +
> +            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
> +            mmap_dst = (memory_map_t *)mbd->mmap;
> +
> +            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)

Coding style.

> +            {
> +                mmap_dst[i].size = sizeof(memory_map_t);
> +                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
> +                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
> +                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
> +                mmap_dst[i].length_low = (u32)mmap_src[i].len;
> +                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
> +                mmap_dst[i].type = mmap_src[i].type;
> +            }
> +            break;
> +
> +        case MULTIBOOT2_TAG_TYPE_MODULE:
> +            mbd_mods[mod_idx].start = (u32)((multiboot2_tag_module_t *)tag)->mod_start;
> +            mbd_mods[mod_idx].end = (u32)((multiboot2_tag_module_t *)tag)->mod_end;
> +            ptr = (u32)((multiboot2_tag_module_t *)tag)->cmdline;
> +            mbd_mods[mod_idx].cmdline = copy_string(ptr);
> +            mbd_mods[mod_idx].relocated = 0;
> +            ++mod_idx;
> +            break;

The massive amount of casts throughout the entire switch is clearly
unfortunate - can you please try to do something about this?

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file
  2014-08-08 23:04 ` [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file Daniel Kiper
@ 2014-08-11 10:35   ` Jan Beulich
  0 siblings, 0 replies; 40+ messages in thread
From: Jan Beulich @ 2014-08-11 10:35 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> xen/include/xen/vga.h just include xen/include/xen/video.h.
> So, remove it because it is redundant file.

A change like this could be applied right away if it wasn't the 6th one
in the series.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-08-11  9:49   ` Jan Beulich
@ 2014-08-11 16:16     ` Stefano Stabellini
  2014-09-03 14:11       ` Ian Campbell
  2014-09-09 13:39     ` Daniel Kiper
  1 sibling, 1 reply; 40+ messages in thread
From: Stefano Stabellini @ 2014-08-11 16:16 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, Daniel Kiper, roy.franz,
	ning.sun, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, 11 Aug 2014, Jan Beulich wrote:
> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> > --- /dev/null
> > +++ b/xen/include/asm-x86/mbd.h
> > @@ -0,0 +1,70 @@
> > +/*
> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#ifndef __MBD_H__
> > +#define __MBD_H__
> > +
> > +/* Module type. */
> > +typedef struct {
> > +    u32 start;
> > +    u32 end;
> > +
> > +    /* Pointer to a module command line. */
> > +    u32 cmdline;
> > +
> > +    /* If relocated != 0 then a given module was relocated. */
> > +    u32 relocated;
> > +} boot_module_t;
> > +
> > +/*
> > + * MultiBoot Data (MBD) type. It is used to define variable which
> > + * carry over data from multiboot protocol (any version) through
> > + * Xen preloader stage. Later all or parts of this data is used
> > + * to initialize Xen Boot Info (XBI) structure.
> > + */
> > +typedef struct {
> > +    /* Pointer to boot loader name. */
> > +    u32 boot_loader_name;
> > +
> > +    /* Pointer to Xen command line. */
> > +    u32 cmdline;
> > +
> > +    /*
> > +     * Amount of lower memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_lower;
> > +
> > +    /*
> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_upper;
> > +
> > +    /* Size (in bytes) of memory map provided by bootloader. */
> > +    u32 mmap_size;
> > +
> > +    /* Pointer to memory map provided by bootloader. */
> > +    u32 mmap;

In what format is the memory map?


> > +    /* Number of modules. */
> > +    u32 mods_nr;
> > +
> > +    /* Pointer to modules description (boot_module_t *). */
> > +    u32 mods;
> > +} mbd_t;
> > +#endif /* __MBD_H__ */
> 
> For several of the fields I wonder whether u32 is really the right
> data type (i.e. whether u64 wouldn't be more correct going
> forward).

Right. From the ARM64 perspective, I don't think that anything mandates
that the bootloader needs to load Xen and/or Linux below 4G.

Also in the interest of code sharing across multiple arches, it seems to
me that these struct should be common code.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
  2014-08-10 16:34   ` Andrew Cooper
  2014-08-11  9:54   ` Jan Beulich
@ 2014-08-11 16:20   ` Stefano Stabellini
  2014-08-11 16:37     ` Stefano Stabellini
  2 siblings, 1 reply; 40+ messages in thread
From: Stefano Stabellini @ 2014-08-11 16:20 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, ross.philipson,
	roy.franz, ning.sun, jbeulich, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Sat, 9 Aug 2014, Daniel Kiper wrote:
> Define Xen Boot Info (XBI) type. This will be used to define variable
> used to store data collected by bootloader and preloader. This way
> we are able to make most of Xen code bootloader agnostic.
> 
> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> ---
>  xen/include/asm-x86/xbi.h |  117 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 117 insertions(+)
>  create mode 100644 xen/include/asm-x86/xbi.h
> 
> diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
> new file mode 100644
> index 0000000..ca9e615
> --- /dev/null
> +++ b/xen/include/asm-x86/xbi.h
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __XBI_H__
> +#define __XBI_H__
> +
> +#include <xen/types.h>
> +#include <xen/vga.h>
> +
> +#include <asm/e820.h>
> +#include <asm/edd.h>
> +#include <asm/mbd.h>
> +
> +/* Xen Boot Info (XBI) type. */
> +typedef struct {
> +    /* Boot loader name. */
> +    char *boot_loader_name;
> +
> +    /* Xen command line. */
> +    char *cmdline;
> +
> +    /* Memory map type (source of memory map). */
> +    char *mmap_type;
> +
> +    /*
> +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> +     * Specification version 0.6.96.
> +     */
> +    u32 mem_upper;
> +
> +    /* Number of memory map entries provided by Xen preloader. */
> +    int e820map_nr;
> +
> +    /*
> +     * Memory map provided by Xen preloader. It should always point
> +     * to an area able to accommodate at least E820MAX entries.
> +     */
> +    struct e820entry *e820map;
> +
> +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
> +    unsigned long efi_mmap_size;
> +
> +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
> +    unsigned long efi_mmap_desc_size;
> +
> +    /* Pointer to EFI memory map provided by preloader. */
> +    void *efi_mmap;
> +
> +    /* Pointer to MPS. */
> +    unsigned long mps;
> +
> +    /* Pointer to ACPI RSDP. */
> +    unsigned long acpi;
> +
> +    /* Pointer to ACPI 2.0 RSDP. */
> +    unsigned long acpi20;
> +
> +    /* Pointer to SMBIOS. */
> +    unsigned long smbios;
> +
> +    /* Pointer to EFI System Table. */
> +    void *efi_system_table;
> +
> +    /* VGA console info. */
> +    struct xen_vga_console_info vga_console_info;
> +
> +    /* EDID info. */
> +    unsigned short edid_caps;
> +    unsigned char *edid_info;
> +
> +    /* Number of EDD entries provided by Xen preloader. */
> +    u8 edd_info_nr;
> +
> +    /* Pointer to EDD info. */
> +    struct edd_info *edd_info;
> +
> +    /* Number of MBR entries provided by Xen preloader. */
> +    u8 mbr_signature_nr;
> +
> +    /* Pointer to MBR info. */
> +    struct mbr_signature *mbr_signature;
> +
> +    /* Number of modules. */
> +    unsigned int mods_nr;
> +
> +    /* Pointer to modules description. */
> +    boot_module_t *mods;
> +
> +    /*
> +     * Info about warning occurred during XBI initialization.
> +     * NULL if everything went OK.
> +     */
> +    char *warn_msg;
> +
> +    /*
> +     * Info about error occurred during XBI initialization. NULL if everything
> +     * went OK. Otherwise XBI is not fully/properly initialized.
> +     */
> +    char *err_msg;
> +} xbi_t;
> +
> +extern xbi_t *xbi;
> +#endif /* __XBI_H__ */
 
If this struct is to become part of an internal cross-arch interface in
Xen, it needs to have an arch specific field. You could move the e820
stuff to the x86 version of it. The only memory map available on ARM is
the UEFI memory map.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-11 16:20   ` Stefano Stabellini
@ 2014-08-11 16:37     ` Stefano Stabellini
  0 siblings, 0 replies; 40+ messages in thread
From: Stefano Stabellini @ 2014-08-11 16:37 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: keir, ian.campbell, Daniel Kiper, ross.philipson, roy.franz,
	ning.sun, jbeulich, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Mon, 11 Aug 2014, Stefano Stabellini wrote:
> On Sat, 9 Aug 2014, Daniel Kiper wrote:
> > Define Xen Boot Info (XBI) type. This will be used to define variable
> > used to store data collected by bootloader and preloader. This way
> > we are able to make most of Xen code bootloader agnostic.
> > 
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > ---
> >  xen/include/asm-x86/xbi.h |  117 +++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 117 insertions(+)
> >  create mode 100644 xen/include/asm-x86/xbi.h
> > 
> > diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
> > new file mode 100644
> > index 0000000..ca9e615
> > --- /dev/null
> > +++ b/xen/include/asm-x86/xbi.h
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#ifndef __XBI_H__
> > +#define __XBI_H__
> > +
> > +#include <xen/types.h>
> > +#include <xen/vga.h>
> > +
> > +#include <asm/e820.h>
> > +#include <asm/edd.h>
> > +#include <asm/mbd.h>
> > +
> > +/* Xen Boot Info (XBI) type. */
> > +typedef struct {
> > +    /* Boot loader name. */
> > +    char *boot_loader_name;
> > +
> > +    /* Xen command line. */
> > +    char *cmdline;
> > +
> > +    /* Memory map type (source of memory map). */
> > +    char *mmap_type;
> > +
> > +    /*
> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_upper;
> > +
> > +    /* Number of memory map entries provided by Xen preloader. */
> > +    int e820map_nr;
> > +
> > +    /*
> > +     * Memory map provided by Xen preloader. It should always point
> > +     * to an area able to accommodate at least E820MAX entries.
> > +     */
> > +    struct e820entry *e820map;
> > +
> > +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
> > +    unsigned long efi_mmap_size;

I would use explicitly sized integers here. Moreover ARM32 supports
LPAE.


> > +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
> > +    unsigned long efi_mmap_desc_size;
> > +
> > +    /* Pointer to EFI memory map provided by preloader. */
> > +    void *efi_mmap;
> > +
> > +    /* Pointer to MPS. */
> > +    unsigned long mps;

Why some pointers are void* and some others are unsigned long?
If this contains a physical address you should say so in the comment.
Also you should use xen_ulong_t or u64.


> > +    /* Pointer to ACPI RSDP. */
> > +    unsigned long acpi;
> > +
> > +    /* Pointer to ACPI 2.0 RSDP. */
> > +    unsigned long acpi20;
> > +
> > +    /* Pointer to SMBIOS. */
> > +    unsigned long smbios;
> > +
> > +    /* Pointer to EFI System Table. */
> > +    void *efi_system_table;
> > +
> > +    /* VGA console info. */
> > +    struct xen_vga_console_info vga_console_info;
> > +
> > +    /* EDID info. */
> > +    unsigned short edid_caps;
> > +    unsigned char *edid_info;
> > +
> > +    /* Number of EDD entries provided by Xen preloader. */
> > +    u8 edd_info_nr;
> > +
> > +    /* Pointer to EDD info. */
> > +    struct edd_info *edd_info;
> > +
> > +    /* Number of MBR entries provided by Xen preloader. */
> > +    u8 mbr_signature_nr;
> > +
> > +    /* Pointer to MBR info. */
> > +    struct mbr_signature *mbr_signature;
> > +
> > +    /* Number of modules. */
> > +    unsigned int mods_nr;
> > +
> > +    /* Pointer to modules description. */
> > +    boot_module_t *mods;
> > +
> > +    /*
> > +     * Info about warning occurred during XBI initialization.
> > +     * NULL if everything went OK.
> > +     */
> > +    char *warn_msg;
> > +
> > +    /*
> > +     * Info about error occurred during XBI initialization. NULL if everything
> > +     * went OK. Otherwise XBI is not fully/properly initialized.
> > +     */
> > +    char *err_msg;
> > +} xbi_t;
> > +
> > +extern xbi_t *xbi;
> > +#endif /* __XBI_H__ */
>  
> If this struct is to become part of an internal cross-arch interface in
> Xen, it needs to have an arch specific field. You could move the e820
> stuff to the x86 version of it. The only memory map available on ARM is
> the UEFI memory map.
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-08-11 16:16     ` Stefano Stabellini
@ 2014-09-03 14:11       ` Ian Campbell
  2014-09-03 15:16         ` Daniel Kiper
  0 siblings, 1 reply; 40+ messages in thread
From: Ian Campbell @ 2014-09-03 14:11 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: keir, Jan Beulich, Daniel Kiper, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Mon, 2014-08-11 at 17:16 +0100, Stefano Stabellini wrote:
> Also in the interest of code sharing across multiple arches, it seems to
> me that these struct should be common code.

I don't intend to block the existing arm64 UEFI work for not using this
new infrastructure, so any code sharing common stuff would have to come
later.

Whether it makes sense to preemptively make this new stuff common I'm
not sure. As it stands the mem_* and mmap(_size) fields aren't really
architecture agnostic.

Ian.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-09-03 14:11       ` Ian Campbell
@ 2014-09-03 15:16         ` Daniel Kiper
  2014-09-04 22:45           ` Stefano Stabellini
  0 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-09-03 15:16 UTC (permalink / raw)
  To: Ian Campbell
  Cc: keir, Jan Beulich, Stefano Stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Wed, Sep 03, 2014 at 03:11:18PM +0100, Ian Campbell wrote:
> On Mon, 2014-08-11 at 17:16 +0100, Stefano Stabellini wrote:
> > Also in the interest of code sharing across multiple arches, it seems to
> > me that these struct should be common code.
>
> I don't intend to block the existing arm64 UEFI work for not using this
> new infrastructure, so any code sharing common stuff would have to come
> later.
>
> Whether it makes sense to preemptively make this new stuff common I'm
> not sure. As it stands the mem_* and mmap(_size) fields aren't really
> architecture agnostic.

I thought about sharing xbi_t instead of mbd_t (please look into patch 2 in
this series). xbi_t could contain arch member (I am not sure about that yet;
Currently my patches use idea similar to page_info struct - I prefer this
solution) which would be used to store arch specific stuff. Fortunately as
I can see only arch specific code touches arch specific members. So it looks
that xbi_t with common members among archs should work on any architecture.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-09-03 15:16         ` Daniel Kiper
@ 2014-09-04 22:45           ` Stefano Stabellini
  0 siblings, 0 replies; 40+ messages in thread
From: Stefano Stabellini @ 2014-09-04 22:45 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, Ian Campbell, Stefano Stabellini, roy.franz, ning.sun,
	Jan Beulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Wed, 3 Sep 2014, Daniel Kiper wrote:
> On Wed, Sep 03, 2014 at 03:11:18PM +0100, Ian Campbell wrote:
> > On Mon, 2014-08-11 at 17:16 +0100, Stefano Stabellini wrote:
> > > Also in the interest of code sharing across multiple arches, it seems to
> > > me that these struct should be common code.
> >
> > I don't intend to block the existing arm64 UEFI work for not using this
> > new infrastructure, so any code sharing common stuff would have to come
> > later.
> >
> > Whether it makes sense to preemptively make this new stuff common I'm
> > not sure. As it stands the mem_* and mmap(_size) fields aren't really
> > architecture agnostic.
> 
> I thought about sharing xbi_t instead of mbd_t (please look into patch 2 in
> this series). xbi_t could contain arch member (I am not sure about that yet;
> Currently my patches use idea similar to page_info struct - I prefer this
> solution) which would be used to store arch specific stuff. Fortunately as
> I can see only arch specific code touches arch specific members. So it looks
> that xbi_t with common members among archs should work on any architecture.

I can see how xbi_t might be a better candidate for sharing. It does
contain a couple of arch specific fields, such as e820map, that could be
moved to an arch specific field.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-08-10 17:05   ` Andrew Cooper
  2014-08-11 10:01     ` Jan Beulich
@ 2014-09-09 13:22     ` Daniel Kiper
  2014-09-09 13:37       ` Jan Beulich
  2014-09-09 13:39       ` Andrew Cooper
  1 sibling, 2 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 13:22 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Hi,

Sorry for late reply but I am recovering after conferences and vacation.

On Sun, Aug 10, 2014 at 06:05:38PM +0100, Andrew Cooper wrote:
> On 09/08/14 00:04, Daniel Kiper wrote:
> > We have all constants and structures in place. So, finally break multiboot (v1)
> > protocol dependency. It means that most of Xen code (excluding preloader)
> > could be bootloader agnostic and does not need almost any knowledge about
> > boot protocol. Additionally, we are able to pass all boot data to __start_xen()
> > in one bucket without any side channels. I do not mention that we are also
> > able to easily identify boot data in Xen code.
> >
> > Here is boot data flow for legacy BIOS platform:
> >
> >   BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
> >                                                         /
> >                      -----------------<-----------------
> >                      \
> >                       \
> >                        ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
> >                       /
> >              BIOS ->-/
> >
> >   * multiboot2 is not implemented yet. Look for it in next patch.
> >
> > Here is boot data flow for EFI platform:
> >
> >   EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI
> >
> > WARNING: ARM build could be broken by this patch. We need to agree XBI
> > integration into ARM. Personally I think that it is worth storing all
> > data from any bootloader and preloader in XBI on any architecture. This
> > give a chance to share more code between architectures. However, every
> > architecture should define its own XBI (in relevant include/asm directory).
> > Despite that it looks that some parts of it could be common, e.g.  modules
> > data, command line arguments, boot loader name, EFI data, etc., even if types
> > would not be the same. So, as it was stated above a lot of code could be
> > shared among architectures.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> This patch is massive, and really needs splitting up somewhat.  There
> are several logically distinct bits to it.

Well... It is quite difficult because original mbi is touched in many places.
So, if you remove its definition then it means that you must remove all references
to it to not break build. Hence, one option which I can see is that we can introduce
MBD in first patch (probably we will need some transitional code which will bind MBD
with mbi used after preloader phase) and later in second patch we can replace mbi
with XBI (or BI, whatever, how we call it is not so important). This way we will have
more or less half of below code in every of two patches. I hope that help.

> > ---
> >  xen/arch/x86/Makefile             |    1 +
> >  xen/arch/x86/boot/cmdline.S       |    9 +-
> >  xen/arch/x86/boot/head.S          |   31 ++--
> >  xen/arch/x86/boot/reloc.c         |  153 ++++++++++++-----
> >  xen/arch/x86/boot/x86_64.S        |   10 +-
> >  xen/arch/x86/dmi_scan.c           |    7 +-
> >  xen/arch/x86/domain_build.c       |   24 +--
> >  xen/arch/x86/efi/boot.c           |  212 +++++++++++------------
> >  xen/arch/x86/efi/efi.h            |    3 -
> >  xen/arch/x86/efi/runtime.c        |   52 ++++--
> >  xen/arch/x86/init_xbi.c           |  254 +++++++++++++++++++++++++++
> >  xen/arch/x86/microcode.c          |   39 ++---
> >  xen/arch/x86/mpparse.c            |    9 +-
> >  xen/arch/x86/platform_hypercall.c |   19 +--
> >  xen/arch/x86/setup.c              |  340 +++++++++++--------------------------
> >  xen/arch/x86/x86_64/asm-offsets.c |    5 +-
> >  xen/drivers/acpi/osl.c            |    9 +-
> >  xen/drivers/video/vesa.c          |    5 +-
> >  xen/drivers/video/vga.c           |   16 +-
> >  xen/include/asm-x86/config.h      |    2 -
> >  xen/include/asm-x86/e820.h        |    8 -
> >  xen/include/asm-x86/edd.h         |    6 -
> >  xen/include/asm-x86/setup.h       |   10 +-
> >  xen/include/xen/efi.h             |   10 --
> >  xen/include/xen/vga.h             |    4 -
> >  xen/include/xsm/xsm.h             |   14 +-
> >  xen/xsm/xsm_core.c                |    6 +-
> >  xen/xsm/xsm_policy.c              |   14 +-
> >  28 files changed, 723 insertions(+), 549 deletions(-)
> >  create mode 100644 xen/arch/x86/init_xbi.c
> >
> > diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
> > index c1e244d..bb2264a 100644
> > --- a/xen/arch/x86/Makefile
> > +++ b/xen/arch/x86/Makefile
> > @@ -42,6 +42,7 @@ obj-y += numa.o
> >  obj-y += pci.o
> >  obj-y += percpu.o
> >  obj-y += physdev.o
> > +obj-y += init_xbi.o
>
> init_xbi is not a fantastic filename.  xbi alone would be better
> (subject to my concerned about the name xbi).
>
> >  obj-y += setup.o
> >  obj-y += shutdown.o
> >  obj-y += smp.o
> > diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
> > index 00687eb..7316011 100644
> > --- a/xen/arch/x86/boot/cmdline.S
> > +++ b/xen/arch/x86/boot/cmdline.S
> > @@ -152,17 +152,14 @@ cmdline_parse_early:
> >          pusha
> >
> >          /* Bail if there is no command line to parse. */
> > -        mov     sym_phys(multiboot_ptr),%ebx
> > -        mov     MB_flags(%ebx),%eax
> > -        test    $4,%al
> > -        jz      .Lcmdline_exit
> > -        mov     MB_cmdline(%ebx),%eax
> > +        mov     sym_phys(mbd_ptr),%ebx
> > +        mov     MBD_cmdline(%ebx),%eax
>
> FLAGS & MBI_CMDLINE is the prerequisite for the 'cmdline' field being
> valid.  You cannot drop that check (although making use of some manifest
> constants would help)

We do not check original mbi struct here. It is MBD and if Xen command line is
empty then MBD_cmdline(%ebx) == 0. Hence, everything works as expected.

> >          test    %eax,%eax
> >          jz      .Lcmdline_exit
> >
> >          /* Check for 'no-real-mode' command-line option. */
> >          pushl   $sym_phys(.Lno_rm_opt)
> > -        pushl   MB_cmdline(%ebx)
> > +        pushl   MBD_cmdline(%ebx)
> >          call    .Lfind_option
> >          test    %eax,%eax
> >          setnz   %al
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> > index 10ecf51..79bce3c 100644
> > --- a/xen/arch/x86/boot/head.S
> > +++ b/xen/arch/x86/boot/head.S
> > @@ -86,14 +86,14 @@ __start:
> >          jne     not_multiboot
> >
> >          /* Set up trampoline segment 64k below EBDA */
> > -        movzwl  0x40e,%eax          /* EBDA segment */
> > -        cmp     $0xa000,%eax        /* sanity check (high) */
> > +        movzwl  0x40e,%ecx          /* EBDA segment */
> > +        cmp     $0xa000,%ecx        /* sanity check (high) */
> >          jae     0f
> > -        cmp     $0x4000,%eax        /* sanity check (low) */
> > +        cmp     $0x4000,%ecx        /* sanity check (low) */
> >          jae     1f
> >  0:
> > -        movzwl  0x413,%eax          /* use base memory size on failure */
> > -        shl     $10-4,%eax
> > +        movzwl  0x413,%ecx          /* use base memory size on failure */
> > +        shl     $10-4,%ecx
> >  1:
> >          /*
> >           * Compare the value in the BDA with the information from the
> > @@ -105,22 +105,23 @@ __start:
> >          cmp     $0x100,%edx         /* is the multiboot value too small? */
> >          jb      2f                  /* if so, do not use it */
> >          shl     $10-4,%edx
> > -        cmp     %eax,%edx           /* compare with BDA value */
> > -        cmovb   %edx,%eax           /* and use the smaller */
> > +        cmp     %ecx,%edx           /* compare with BDA value */
> > +        cmovb   %edx,%ecx           /* and use the smaller */
> >
> >  2:      /* Reserve 64kb for the trampoline */
> > -        sub     $0x1000,%eax
> > +        sub     $0x1000,%ecx
> >
> >          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
> > -        xor     %al, %al
> > -        shl     $4, %eax
> > -        mov     %eax,sym_phys(trampoline_phys)
> > +        xor     %cl, %cl
> > +        shl     $4, %ecx
> > +        mov     %ecx,sym_phys(trampoline_phys)
> >
> > -        /* Save the Multiboot info struct (after relocation) for later use. */
> > +        /* Save the Multiboot data (after relocation) for later use. */
> >          mov     $sym_phys(cpu0_stack)+1024,%esp
> > -        push    %ebx
> > -        call    reloc
> > -        mov     %eax,sym_phys(multiboot_ptr)
> > +        push    %eax                /* Multiboot magic */
> > +        push    %ebx                /* Multiboot information address */
> > +        call    reloc               /* %ecx contains trampoline address */
> > +        mov     %eax,sym_phys(mbd_ptr)
> >
> >          /* Initialize BSS (no nasty surprises!) */
> >          mov     $sym_phys(__bss_start),%edi
> > diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
> > index fa0fb6b..29f4887 100644
> > --- a/xen/arch/x86/boot/reloc.c
> > +++ b/xen/arch/x86/boot/reloc.c

[...]

> > +static void zero_struct(u32 s, u32 bytes)
> > +{
> > +    asm volatile(
> > +    "    cld                          \n"
>
> __start has already performed cld for us.  There is nothing which will
> have set it between then and here.

Hmmm... Are we sure that gcc will not insert an instruction
which will change direction flag? cld does not cost a lot
and we will be on safe side here.

[...]

> > + * __THIS__ IS NOT ENTRY POINT!!!
> > + * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
>
> I don't think this needs stating...

It is not obvious. I spent some time to discover this. I do not
mention that strange build method does not ease reading and
understanding. I think that it is worth saving time of other
guys who will read this file first time.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-08-10 17:23   ` Andrew Cooper
@ 2014-09-09 13:34     ` Daniel Kiper
  2014-09-09 13:43       ` Andrew Cooper
  0 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 13:34 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Sun, Aug 10, 2014 at 06:23:55PM +0100, Andrew Cooper wrote:
> On 09/08/14 00:04, Daniel Kiper wrote:
> > Add multiboot2 protocol support. This way we are laying the foundation
> > for EFI + GRUB2 + Xen development.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
> > ---
> >  xen/arch/x86/boot/head.S  |  112 ++++++++++++++++++++++++++++++++++++++++++++-
> >  xen/arch/x86/boot/reloc.c |  103 ++++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 212 insertions(+), 3 deletions(-)
> >
> > diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S

[...]

> > @@ -81,10 +144,55 @@ __start:
> >          mov     %ecx,%es
> >          mov     %ecx,%ss
> >
> > +        /* Set mem_lower to 0 */
> > +        xor     %edx,%edx
> > +
>
> How does this affect mem_lower? it doesn't appear relevant in context.

%edx is used to store mem_lower value from multiboot[12] protocol. It must
have sensible value even if multiboot loader do not pass mem_lower value.
That is why %edx is zeroed here.

> >          /* Check for Multiboot bootloader */
> > -        cmp     $0x2BADB002,%eax
> > -        jne     not_multiboot
> > +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> > +        je      1f
>
> This $MULTIBOOT_BOOTLOADER_MAGIC should probably be separate, as there
> are other bits of code which should use multiboot manifest constants.

You mean?

> It looks as if this should be "je multiboot1_entry" ...

OK.

> > +
> > +        /* Check for Multiboot2 bootloader */
> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +        je      2f
> > +
> > +        jmp     not_multiboot
> > +
> > +1:
> > +        /* Get mem_lower from Multiboot information */
> > +        testb   $MBI_MEMLIMITS,(%ebx)
> > +        jz      0f                  /* not available? BDA value will be fine */
> >
> > +        mov     4(%ebx),%edx
> > +        shl     $10-4,%edx
> > +        jmp     0f
>
> and these 0f's should be "setup_trampoline" or similar.  You have also

OK.

> removed some sanity checks of the multiboot information, which need
> reintroducing.

No, here we are just reading basic data passed via multiboot[12] protocol.
All needed checks are done later. Relevant code is not changed (excluding
some register shuffling done in earlier patch).

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-09-09 13:22     ` Daniel Kiper
@ 2014-09-09 13:37       ` Jan Beulich
  2014-09-09 13:39       ` Andrew Cooper
  1 sibling, 0 replies; 40+ messages in thread
From: Jan Beulich @ 2014-09-09 13:37 UTC (permalink / raw)
  To: Andrew Cooper, Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.09.14 at 15:22, <daniel.kiper@oracle.com> wrote:
> On Sun, Aug 10, 2014 at 06:05:38PM +0100, Andrew Cooper wrote:
>> On 09/08/14 00:04, Daniel Kiper wrote:
>> > +static void zero_struct(u32 s, u32 bytes)
>> > +{
>> > +    asm volatile(
>> > +    "    cld                          \n"
>>
>> __start has already performed cld for us.  There is nothing which will
>> have set it between then and here.
> 
> Hmmm... Are we sure that gcc will not insert an instruction
> which will change direction flag? cld does not cost a lot
> and we will be on safe side here.

Just consider in how many other places we'd need CLD if gcc was
permitted to play freely with EFLAGS.DF.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
  2014-09-09 13:22     ` Daniel Kiper
  2014-09-09 13:37       ` Jan Beulich
@ 2014-09-09 13:39       ` Andrew Cooper
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Cooper @ 2014-09-09 13:39 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On 09/09/14 14:22, Daniel Kiper wrote:
> Hi,
>
> Sorry for late reply but I am recovering after conferences and vacation.
>
> On Sun, Aug 10, 2014 at 06:05:38PM +0100, Andrew Cooper wrote:
>> On 09/08/14 00:04, Daniel Kiper wrote:
>>> We have all constants and structures in place. So, finally break multiboot (v1)
>>> protocol dependency. It means that most of Xen code (excluding preloader)
>>> could be bootloader agnostic and does not need almost any knowledge about
>>> boot protocol. Additionally, we are able to pass all boot data to __start_xen()
>>> in one bucket without any side channels. I do not mention that we are also
>>> able to easily identify boot data in Xen code.
>>>
>>> Here is boot data flow for legacy BIOS platform:
>>>
>>>   BIOS -> GRUB -> multiboot[12]* -> __reloc() -> MBD ->-\
>>>                                                         /
>>>                      -----------------<-----------------
>>>                      \
>>>                       \
>>>                        ---> __init_xbi() -> XBI_MB -> __start_xen() -> XBI
>>>                       /
>>>              BIOS ->-/
>>>
>>>   * multiboot2 is not implemented yet. Look for it in next patch.
>>>
>>> Here is boot data flow for EFI platform:
>>>
>>>   EFI -> efi_start() -> XBI_EFI -> __start_xen() -> XBI
>>>
>>> WARNING: ARM build could be broken by this patch. We need to agree XBI
>>> integration into ARM. Personally I think that it is worth storing all
>>> data from any bootloader and preloader in XBI on any architecture. This
>>> give a chance to share more code between architectures. However, every
>>> architecture should define its own XBI (in relevant include/asm directory).
>>> Despite that it looks that some parts of it could be common, e.g.  modules
>>> data, command line arguments, boot loader name, EFI data, etc., even if types
>>> would not be the same. So, as it was stated above a lot of code could be
>>> shared among architectures.
>>>
>>> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>> This patch is massive, and really needs splitting up somewhat.  There
>> are several logically distinct bits to it.
> Well... It is quite difficult because original mbi is touched in many places.
> So, if you remove its definition then it means that you must remove all references
> to it to not break build. Hence, one option which I can see is that we can introduce
> MBD in first patch (probably we will need some transitional code which will bind MBD
> with mbi used after preloader phase) and later in second patch we can replace mbi
> with XBI (or BI, whatever, how we call it is not so important). This way we will have
> more or less half of below code in every of two patches. I hope that help.

I am not suggesting that you should avoid large patches per se, but I am
very definitely telling you to split the logically distinct bits into
separate patches. 

Even for dependent logic, some can be split up while retaining
bisectability.  Move the multiboot stuff in a separate patch to the
other bits xbi bits.

>
>>> ---
>>>  xen/arch/x86/Makefile             |    1 +
>>>  xen/arch/x86/boot/cmdline.S       |    9 +-
>>>  xen/arch/x86/boot/head.S          |   31 ++--
>>>  xen/arch/x86/boot/reloc.c         |  153 ++++++++++++-----
>>>  xen/arch/x86/boot/x86_64.S        |   10 +-
>>>  xen/arch/x86/dmi_scan.c           |    7 +-
>>>  xen/arch/x86/domain_build.c       |   24 +--
>>>  xen/arch/x86/efi/boot.c           |  212 +++++++++++------------
>>>  xen/arch/x86/efi/efi.h            |    3 -
>>>  xen/arch/x86/efi/runtime.c        |   52 ++++--
>>>  xen/arch/x86/init_xbi.c           |  254 +++++++++++++++++++++++++++
>>>  xen/arch/x86/microcode.c          |   39 ++---
>>>  xen/arch/x86/mpparse.c            |    9 +-
>>>  xen/arch/x86/platform_hypercall.c |   19 +--
>>>  xen/arch/x86/setup.c              |  340 +++++++++++--------------------------
>>>  xen/arch/x86/x86_64/asm-offsets.c |    5 +-
>>>  xen/drivers/acpi/osl.c            |    9 +-
>>>  xen/drivers/video/vesa.c          |    5 +-
>>>  xen/drivers/video/vga.c           |   16 +-
>>>  xen/include/asm-x86/config.h      |    2 -
>>>  xen/include/asm-x86/e820.h        |    8 -
>>>  xen/include/asm-x86/edd.h         |    6 -
>>>  xen/include/asm-x86/setup.h       |   10 +-
>>>  xen/include/xen/efi.h             |   10 --
>>>  xen/include/xen/vga.h             |    4 -
>>>  xen/include/xsm/xsm.h             |   14 +-
>>>  xen/xsm/xsm_core.c                |    6 +-
>>>  xen/xsm/xsm_policy.c              |   14 +-
>>>  28 files changed, 723 insertions(+), 549 deletions(-)
>>>  create mode 100644 xen/arch/x86/init_xbi.c
>>>
>>> diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
>>> index c1e244d..bb2264a 100644
>>> --- a/xen/arch/x86/Makefile
>>> +++ b/xen/arch/x86/Makefile
>>> @@ -42,6 +42,7 @@ obj-y += numa.o
>>>  obj-y += pci.o
>>>  obj-y += percpu.o
>>>  obj-y += physdev.o
>>> +obj-y += init_xbi.o
>> init_xbi is not a fantastic filename.  xbi alone would be better
>> (subject to my concerned about the name xbi).
>>
>>>  obj-y += setup.o
>>>  obj-y += shutdown.o
>>>  obj-y += smp.o
>>> diff --git a/xen/arch/x86/boot/cmdline.S b/xen/arch/x86/boot/cmdline.S
>>> index 00687eb..7316011 100644
>>> --- a/xen/arch/x86/boot/cmdline.S
>>> +++ b/xen/arch/x86/boot/cmdline.S
>>> @@ -152,17 +152,14 @@ cmdline_parse_early:
>>>          pusha
>>>
>>>          /* Bail if there is no command line to parse. */
>>> -        mov     sym_phys(multiboot_ptr),%ebx
>>> -        mov     MB_flags(%ebx),%eax
>>> -        test    $4,%al
>>> -        jz      .Lcmdline_exit
>>> -        mov     MB_cmdline(%ebx),%eax
>>> +        mov     sym_phys(mbd_ptr),%ebx
>>> +        mov     MBD_cmdline(%ebx),%eax
>> FLAGS & MBI_CMDLINE is the prerequisite for the 'cmdline' field being
>> valid.  You cannot drop that check (although making use of some manifest
>> constants would help)
> We do not check original mbi struct here. It is MBD and if Xen command line is
> empty then MBD_cmdline(%ebx) == 0. Hence, everything works as expected.

Right - this really not clear that the structure pointed to by ebx has
changed, as well as MBD_cmdline having nothing to do with MB_cmdline. 
Again, all of this would be clear with a smaller patch whose description
states "moving multiboot data from format FOO to format BAR"

>
>>>          test    %eax,%eax
>>>          jz      .Lcmdline_exit
>>>
>>>          /* Check for 'no-real-mode' command-line option. */
>>>          pushl   $sym_phys(.Lno_rm_opt)
>>> -        pushl   MB_cmdline(%ebx)
>>> +        pushl   MBD_cmdline(%ebx)
>>>          call    .Lfind_option
>>>          test    %eax,%eax
>>>          setnz   %al
>>> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
>>> index 10ecf51..79bce3c 100644
>>> --- a/xen/arch/x86/boot/head.S
>>> +++ b/xen/arch/x86/boot/head.S
>>> @@ -86,14 +86,14 @@ __start:
>>>          jne     not_multiboot
>>>
>>>          /* Set up trampoline segment 64k below EBDA */
>>> -        movzwl  0x40e,%eax          /* EBDA segment */
>>> -        cmp     $0xa000,%eax        /* sanity check (high) */
>>> +        movzwl  0x40e,%ecx          /* EBDA segment */
>>> +        cmp     $0xa000,%ecx        /* sanity check (high) */
>>>          jae     0f
>>> -        cmp     $0x4000,%eax        /* sanity check (low) */
>>> +        cmp     $0x4000,%ecx        /* sanity check (low) */
>>>          jae     1f
>>>  0:
>>> -        movzwl  0x413,%eax          /* use base memory size on failure */
>>> -        shl     $10-4,%eax
>>> +        movzwl  0x413,%ecx          /* use base memory size on failure */
>>> +        shl     $10-4,%ecx
>>>  1:
>>>          /*
>>>           * Compare the value in the BDA with the information from the
>>> @@ -105,22 +105,23 @@ __start:
>>>          cmp     $0x100,%edx         /* is the multiboot value too small? */
>>>          jb      2f                  /* if so, do not use it */
>>>          shl     $10-4,%edx
>>> -        cmp     %eax,%edx           /* compare with BDA value */
>>> -        cmovb   %edx,%eax           /* and use the smaller */
>>> +        cmp     %ecx,%edx           /* compare with BDA value */
>>> +        cmovb   %edx,%ecx           /* and use the smaller */
>>>
>>>  2:      /* Reserve 64kb for the trampoline */
>>> -        sub     $0x1000,%eax
>>> +        sub     $0x1000,%ecx
>>>
>>>          /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
>>> -        xor     %al, %al
>>> -        shl     $4, %eax
>>> -        mov     %eax,sym_phys(trampoline_phys)
>>> +        xor     %cl, %cl
>>> +        shl     $4, %ecx
>>> +        mov     %ecx,sym_phys(trampoline_phys)
>>>
>>> -        /* Save the Multiboot info struct (after relocation) for later use. */
>>> +        /* Save the Multiboot data (after relocation) for later use. */
>>>          mov     $sym_phys(cpu0_stack)+1024,%esp
>>> -        push    %ebx
>>> -        call    reloc
>>> -        mov     %eax,sym_phys(multiboot_ptr)
>>> +        push    %eax                /* Multiboot magic */
>>> +        push    %ebx                /* Multiboot information address */
>>> +        call    reloc               /* %ecx contains trampoline address */
>>> +        mov     %eax,sym_phys(mbd_ptr)
>>>
>>>          /* Initialize BSS (no nasty surprises!) */
>>>          mov     $sym_phys(__bss_start),%edi
>>> diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c
>>> index fa0fb6b..29f4887 100644
>>> --- a/xen/arch/x86/boot/reloc.c
>>> +++ b/xen/arch/x86/boot/reloc.c
> [...]
>
>>> +static void zero_struct(u32 s, u32 bytes)
>>> +{
>>> +    asm volatile(
>>> +    "    cld                          \n"
>> __start has already performed cld for us.  There is nothing which will
>> have set it between then and here.
> Hmmm... Are we sure that gcc will not insert an instruction
> which will change direction flag?

Absolutely sure.

>  cld does not cost a lot
> and we will be on safe side here.

We clear it on all entry points into Xen as we can't trust our caller
not to mess with it, but we absolutely can trust our own compiled code
not to.

>
> [...]
>
>>> + * __THIS__ IS NOT ENTRY POINT!!!
>>> + * PLEASE LOOK AT THE BEGINNING OF THIS FILE!!!
>> I don't think this needs stating...
> It is not obvious. I spent some time to discover this. I do not
> mention that strange build method does not ease reading and
> understanding. I think that it is worth saving time of other
> guys who will read this file first time.
>
> Daniel

The _start symbol is at the top of the file.  It is obviously not at
this point.

~Andrew

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-08-11  9:49   ` Jan Beulich
  2014-08-11 16:16     ` Stefano Stabellini
@ 2014-09-09 13:39     ` Daniel Kiper
  2014-09-09 14:28       ` Jan Beulich
  1 sibling, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 13:39 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Mon, Aug 11, 2014 at 10:49:15AM +0100, Jan Beulich wrote:
> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> > --- /dev/null
> > +++ b/xen/include/asm-x86/mbd.h
> > @@ -0,0 +1,70 @@
> > +/*
> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#ifndef __MBD_H__
> > +#define __MBD_H__
> > +
> > +/* Module type. */
> > +typedef struct {
> > +    u32 start;
> > +    u32 end;
> > +
> > +    /* Pointer to a module command line. */
> > +    u32 cmdline;
> > +
> > +    /* If relocated != 0 then a given module was relocated. */
> > +    u32 relocated;
> > +} boot_module_t;
> > +
> > +/*
> > + * MultiBoot Data (MBD) type. It is used to define variable which
> > + * carry over data from multiboot protocol (any version) through
> > + * Xen preloader stage. Later all or parts of this data is used
> > + * to initialize Xen Boot Info (XBI) structure.
> > + */
> > +typedef struct {
> > +    /* Pointer to boot loader name. */
> > +    u32 boot_loader_name;
> > +
> > +    /* Pointer to Xen command line. */
> > +    u32 cmdline;
> > +
> > +    /*
> > +     * Amount of lower memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_lower;
> > +
> > +    /*
> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_upper;
> > +
> > +    /* Size (in bytes) of memory map provided by bootloader. */
> > +    u32 mmap_size;
> > +
> > +    /* Pointer to memory map provided by bootloader. */
> > +    u32 mmap;
> > +
> > +    /* Number of modules. */
> > +    u32 mods_nr;
> > +
> > +    /* Pointer to modules description (boot_module_t *). */
> > +    u32 mods;
> > +} mbd_t;
> > +#endif /* __MBD_H__ */
>
> For several of the fields I wonder whether u32 is really the right
> data type (i.e. whether u64 wouldn't be more correct going
> forward).

All data which we get from multiboot[12] is u32. So, I think it does not
make sense to use u64 here.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-09-09 13:34     ` Daniel Kiper
@ 2014-09-09 13:43       ` Andrew Cooper
  0 siblings, 0 replies; 40+ messages in thread
From: Andrew Cooper @ 2014-09-09 13:43 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On 09/09/14 14:34, Daniel Kiper wrote:
> On Sun, Aug 10, 2014 at 06:23:55PM +0100, Andrew Cooper wrote:
>> On 09/08/14 00:04, Daniel Kiper wrote:
>>> Add multiboot2 protocol support. This way we are laying the foundation
>>> for EFI + GRUB2 + Xen development.
>>>
>>> Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>>> ---
>>>  xen/arch/x86/boot/head.S  |  112 ++++++++++++++++++++++++++++++++++++++++++++-
>>>  xen/arch/x86/boot/reloc.c |  103 ++++++++++++++++++++++++++++++++++++++++-
>>>  2 files changed, 212 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
> [...]
>
>>> @@ -81,10 +144,55 @@ __start:
>>>          mov     %ecx,%es
>>>          mov     %ecx,%ss
>>>
>>> +        /* Set mem_lower to 0 */
>>> +        xor     %edx,%edx
>>> +
>> How does this affect mem_lower? it doesn't appear relevant in context.
> %edx is used to store mem_lower value from multiboot[12] protocol. It must
> have sensible value even if multiboot loader do not pass mem_lower value.
> That is why %edx is zeroed here.
>
>>>          /* Check for Multiboot bootloader */
>>> -        cmp     $0x2BADB002,%eax
>>> -        jne     not_multiboot
>>> +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
>>> +        je      1f
>> This $MULTIBOOT_BOOTLOADER_MAGIC should probably be separate, as there
>> are other bits of code which should use multiboot manifest constants.
> You mean?

A cleanup patch changing $0x2BADB002 -> $MULTIBOOT_BOOTLOADER_MAGIC
should be separate from a functional change of adding multiboot 2 support.

There are other places where you have mixed cleanup with adding new
functionality.

Cleanup is fine, but it *must* be separate from functional changes. 
Reviewing asm code is hard enough without having to work out whether the
change is functional or cleanup, or a mix of the two.

~Andrew

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 3/7] xen: Add multiboot2.h header file
  2014-08-11  9:58   ` Jan Beulich
@ 2014-09-09 13:47     ` Daniel Kiper
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 13:47 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Mon, Aug 11, 2014 at 10:58:07AM +0100, Jan Beulich wrote:
> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> > --- /dev/null
> > +++ b/xen/include/xen/multiboot2.h
>
> I have to admit that I can't see why this can't all go into
> xen/include/xen/multiboot.h - the two sets of definitions have to be
> able to coexist anyway.

They could coexist. However, I think that both protocols are different and
it will be less confusion if relevant definition will stay in separate files.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-08-11 10:33   ` Jan Beulich
@ 2014-09-09 14:21     ` Daniel Kiper
  2014-09-09 14:36       ` Jan Beulich
  0 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 14:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Mon, Aug 11, 2014 at 11:33:32AM +0100, Jan Beulich wrote:
> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> > @@ -33,6 +34,68 @@ ENTRY(start)
> >          /* Checksum: must be the negated sum of the first two fields. */
> >          .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
> >
> > +/*** MULTIBOOT2 HEADER ****/
> > +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */
> > +        .align  MULTIBOOT2_HEADER_ALIGN
> > +
> > +multiboot2_header:
>
> While I'm fine with this label, ...
>
> > +        /* Magic number indicating a Multiboot2 header. */
> > +        .long   MULTIBOOT2_HEADER_MAGIC
> > +        /* Architecture: i386. */
> > +        .long   MULTIBOOT2_ARCHITECTURE_I386
> > +        /* Multiboot2 header length. */
> > +        .long   multiboot2_header_end - multiboot2_header
> > +        /* Multiboot2 header checksum. */
> > +        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \
> > +                        (multiboot2_header_end - multiboot2_header))
> > +
> > +        /* Multiboot2 tags... */
> > +multiboot2_info_req:
>
> ... this and ...
>
> > +        /* Multiboot2 information request tag. */
> > +        .short  MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST
> > +        .short  MULTIBOOT2_HEADER_TAG_REQUIRED
> > +        .long   multiboot2_info_req_end - multiboot2_info_req
> > +        .long   MULTIBOOT2_TAG_TYPE_MMAP
> > +multiboot2_info_req_end:
>
> ... this are purely auxiliary and as such shouldn't end up in the
> symbol table. Please prefix such labels with ".L".

OK.

> > +
> > +        /*
> > +         * Align Xen image and modules at page boundry.
> > +         *
> > +         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
> > +         * to avoid bug related to Multiboot2 information request tag in earlier
> > +         * versions of GRUB2.
> > +         *
> > +         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
> > +         * WITH EARLIER GRUB2 VERSIONS!
> > +         */
>
> Question is - since your ultimate goal of getting UEFI to work this way
> won't be achievable with older GrUB2 anyway, do we care at all? Also,

I think that it makes sense to have multiboot2 protocol implementation
working on every GRUB2 version. This way it will be quite easy to use
that same Xen image regardless of GRUB and multiboot protocol version.
Additionally, I discovered that above mentioned bug depends on multiboot2_info_req
contents which is very annoying and not very easy to discover. So, this
hack ensures that regardless of multiboot2_info_req contents Xen image
behaves always in the same way on every GRUB2 version (with or without bug).

> at least a reasonable hint towards the nature of the referenced bug
> should be added here, as in the end it's not too unlikely for there to
> be more than one bug in an area like this. I.e. future people reading
> this or working on the code should have a handle to decide whether
> the hack is still applicable without first having to guess which specific
> bug this is about.

OK.

> > +        .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END
> > +        .short   MULTIBOOT2_HEADER_TAG_MODULE_ALIGN
> > +        .short   MULTIBOOT2_HEADER_TAG_REQUIRED
>
> Readability would certainly benefit if you macro-ized the tag
> generation, at least to avoid the many redundant
> MULTIBOOT2_HEADER_TAG_ prefixes (but perhaps also the
> alignment).

OK.

> > +        .long    8 /* Tag size. */
> > +
> > +        /* Console flags tag. */
> > +        .align  MULTIBOOT2_TAG_ALIGN
> > +        .short  MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS
> > +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> > +        .long   12 /* Tag size. */
> > +        .long   MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED
> > +
> > +        /* Framebuffer tag. */
> > +        .align  MULTIBOOT2_TAG_ALIGN
> > +        .short  MULTIBOOT2_HEADER_TAG_FRAMEBUFFER
> > +        .short  MULTIBOOT2_HEADER_TAG_OPTIONAL
> > +        .long   20 /* Tag size. */
> > +        .long   0 /* Number of the columns - no preference. */
> > +        .long   0 /* Number of the lines - no preference. */
> > +        .long   0 /* Number of bits per pixel - no preference. */
> > +
> > +        /* Multiboot2 header end tag. */
> > +        .align  MULTIBOOT2_TAG_ALIGN
> > +        .short  MULTIBOOT2_HEADER_TAG_END
> > +        .short  0
> > +        .long   8 /* Tag size. */
> > +multiboot2_header_end:
> > +
> >          .section .init.rodata, "a", @progbits
> >          .align 4
> >
> > @@ -81,10 +144,55 @@ __start:
> >          mov     %ecx,%es
> >          mov     %ecx,%ss
> >
> > +        /* Set mem_lower to 0 */
> > +        xor     %edx,%edx
> > +
> >          /* Check for Multiboot bootloader */
> > -        cmp     $0x2BADB002,%eax
> > -        jne     not_multiboot
> > +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> > +        je      1f
> > +
> > +        /* Check for Multiboot2 bootloader */
> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> > +        je      2f
> > +
> > +        jmp     not_multiboot
> > +
> > +1:
> > +        /* Get mem_lower from Multiboot information */
> > +        testb   $MBI_MEMLIMITS,(%ebx)
> > +        jz      0f                  /* not available? BDA value will be fine */
> >
> > +        mov     4(%ebx),%edx
> > +        shl     $10-4,%edx
> > +        jmp     0f
>
> This code isn't being moved here from elsewhere, but also isn't
> multiboot2 related - what's this about? If it's really needed for
> something, this should be in a separate patch imo.

Here we are reading data from multiboot[1] protocol. Label
below is start of multiboot2 protocol implementation. We
need rearrange a bit multiboot[1] protocol implementation
to have both protocols working.

> > +2:
> > +        /* Get Multiboot2 information address */
> > +        mov     %ebx,%ecx
> > +        add     $8,%ecx
> > +
> > +3:
> > +        /* Get mem_lower from Multiboot2 information */
> > +        cmpl    $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,(%ecx)
> > +        jne     4f
> > +
> > +        mov     8(%ecx),%edx
> > +        shl     $10-4,%edx
> > +        jmp     5f
> > +
> > +4:
> > +        /* Is it the end of Multiboot2 information? */
> > +        cmpl    $MULTIBOOT2_TAG_TYPE_END,(%ecx)
> > +        je      0f
> > +
> > +5:
> > +        /* Go to next Multiboot2 information tag */
> > +        add     4(%ecx),%ecx
> > +        add     $(MULTIBOOT2_TAG_ALIGN-1),%ecx
> > +        and     $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
> > +        jmp     3b
> > +
> > +0:
>
> Please consider giving some or all, but at the very least the last,
> labels descriptive names instead of just using numeric ones.

OK.

>
> > --- a/xen/arch/x86/boot/reloc.c
> > +++ b/xen/arch/x86/boot/reloc.c
> > @@ -18,8 +18,12 @@ typedef unsigned long u32;
> >  typedef unsigned long long u64;
> >
> >  #include "../../../include/xen/multiboot.h"
> > +#include "../../../include/xen/multiboot2.h"
> >  #include "../../../include/asm/mbd.h"
> >
> > +#define ALIGN_UP(addr, align) \
> > +                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align - 1))
>
> Even if just used locally, please make sure such macros are properly
> parenthesized.

You mean?

> > @@ -144,6 +148,100 @@ static mbd_t *mb_mbd(mbd_t *mbd, multiboot_info_t *mbi)
> >      return mbd;
> >  }
> >
> > +static mbd_t *mb2_mbd(mbd_t *mbd, void *mbi)
> > +{
> > +    int i, mod_idx = 0;
>
> unsigned for both afaict.

OK.

> > +    memory_map_t *mmap_dst;
> > +    multiboot2_memory_map_t *mmap_src;
> > +    multiboot2_tag_t *tag;
> > +    u32 ptr;
> > +    boot_module_t *mbd_mods;
> > +
> > +    /* Skip Multiboot2 information fixed part. */
> > +    tag = mbi + sizeof(u32) * 2;
>
> Is there no way to properly express this via e.g. an offsetof()?

I will check it.

> > +
> > +    while ( 1 )
>
> To avoid "condition is constant warnings" on certain compilers, I'd
> recommend using for ( ; ; ) instead of while ( 1 ).

OK.

> > +    {
> > +        if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE )
> > +            ++mbd->mods_nr;
> > +        else if ( tag->type == MULTIBOOT2_TAG_TYPE_END )
> > +        {
> > +            mbd->mods = alloc_struct(mbd->mods_nr * sizeof(boot_module_t));
> > +            mbd_mods = (boot_module_t *)mbd->mods;
> > +            break;
> > +        }
> > +
> > +        /* Go to next Multiboot2 information tag. */
> > +        tag = (multiboot2_tag_t *)(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN));
> > +    }
> > +
> > +    /* Skip Multiboot2 information fixed part. */
> > +    tag = mbi + sizeof(u32) * 2;
> > +
> > +    while ( 1 )
> > +    {
> > +        switch ( tag->type )
> > +        {
> > +        case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME:
> > +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> > +            mbd->boot_loader_name = copy_string(ptr);
> > +            break;
> > +
> > +        case MULTIBOOT2_TAG_TYPE_CMDLINE:
> > +            ptr = (u32)((multiboot2_tag_string_t *)tag)->string;
> > +            mbd->cmdline = copy_string(ptr);
> > +            break;
> > +
> > +        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
> > +            mbd->mem_lower = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_lower;
> > +            mbd->mem_upper = ((multiboot2_tag_basic_meminfo_t *)tag)->mem_upper;
> > +            break;
> > +
> > +        case MULTIBOOT2_TAG_TYPE_MMAP:
> > +            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
> > +            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
> > +            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
> > +            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
> > +            mbd->mmap_size *= sizeof(memory_map_t);
> > +
> > +            mbd->mmap = alloc_struct(mbd->mmap_size);
> > +
> > +            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
> > +            mmap_dst = (memory_map_t *)mbd->mmap;
> > +
> > +            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)
>
> Coding style.

You mean?

> > +            {
> > +                mmap_dst[i].size = sizeof(memory_map_t);
> > +                mmap_dst[i].size -= sizeof(((memory_map_t){0}).size);
> > +                mmap_dst[i].base_addr_low = (u32)mmap_src[i].addr;
> > +                mmap_dst[i].base_addr_high = (u32)(mmap_src[i].addr >> 32);
> > +                mmap_dst[i].length_low = (u32)mmap_src[i].len;
> > +                mmap_dst[i].length_high = (u32)(mmap_src[i].len >> 32);
> > +                mmap_dst[i].type = mmap_src[i].type;
> > +            }
> > +            break;
> > +
> > +        case MULTIBOOT2_TAG_TYPE_MODULE:
> > +            mbd_mods[mod_idx].start = (u32)((multiboot2_tag_module_t *)tag)->mod_start;
> > +            mbd_mods[mod_idx].end = (u32)((multiboot2_tag_module_t *)tag)->mod_end;
> > +            ptr = (u32)((multiboot2_tag_module_t *)tag)->cmdline;
> > +            mbd_mods[mod_idx].cmdline = copy_string(ptr);
> > +            mbd_mods[mod_idx].relocated = 0;
> > +            ++mod_idx;
> > +            break;
>
> The massive amount of casts throughout the entire switch is clearly
> unfortunate - can you please try to do something about this?

I will try to fix it.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-09-09 13:39     ` Daniel Kiper
@ 2014-09-09 14:28       ` Jan Beulich
  2014-09-09 15:57         ` Daniel Kiper
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Beulich @ 2014-09-09 14:28 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.09.14 at 15:39, <daniel.kiper@oracle.com> wrote:
> On Mon, Aug 11, 2014 at 10:49:15AM +0100, Jan Beulich wrote:
>> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
>> > --- /dev/null
>> > +++ b/xen/include/asm-x86/mbd.h
>> > @@ -0,0 +1,70 @@
>> > +/*
>> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License as published by
>> > + * the Free Software Foundation; either version 2 of the License, or
>> > + * (at your option) any later version.
>> > + *
>> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
>> > + */
>> > +
>> > +#ifndef __MBD_H__
>> > +#define __MBD_H__
>> > +
>> > +/* Module type. */
>> > +typedef struct {
>> > +    u32 start;
>> > +    u32 end;
>> > +
>> > +    /* Pointer to a module command line. */
>> > +    u32 cmdline;
>> > +
>> > +    /* If relocated != 0 then a given module was relocated. */
>> > +    u32 relocated;
>> > +} boot_module_t;
>> > +
>> > +/*
>> > + * MultiBoot Data (MBD) type. It is used to define variable which
>> > + * carry over data from multiboot protocol (any version) through
>> > + * Xen preloader stage. Later all or parts of this data is used
>> > + * to initialize Xen Boot Info (XBI) structure.
>> > + */
>> > +typedef struct {
>> > +    /* Pointer to boot loader name. */
>> > +    u32 boot_loader_name;
>> > +
>> > +    /* Pointer to Xen command line. */
>> > +    u32 cmdline;
>> > +
>> > +    /*
>> > +     * Amount of lower memory (in KiB) accordingly to The Multiboot
>> > +     * Specification version 0.6.96.
>> > +     */
>> > +    u32 mem_lower;
>> > +
>> > +    /*
>> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
>> > +     * Specification version 0.6.96.
>> > +     */
>> > +    u32 mem_upper;
>> > +
>> > +    /* Size (in bytes) of memory map provided by bootloader. */
>> > +    u32 mmap_size;
>> > +
>> > +    /* Pointer to memory map provided by bootloader. */
>> > +    u32 mmap;
>> > +
>> > +    /* Number of modules. */
>> > +    u32 mods_nr;
>> > +
>> > +    /* Pointer to modules description (boot_module_t *). */
>> > +    u32 mods;
>> > +} mbd_t;
>> > +#endif /* __MBD_H__ */
>>
>> For several of the fields I wonder whether u32 is really the right
>> data type (i.e. whether u64 wouldn't be more correct going
>> forward).
> 
> All data which we get from multiboot[12] is u32. So, I think it does not
> make sense to use u64 here.

Wasn't your proposal to make this an abstraction? If so, what
does the (current) data source have to do with the types here?

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-09-09 14:21     ` Daniel Kiper
@ 2014-09-09 14:36       ` Jan Beulich
  2014-09-09 16:04         ` Daniel Kiper
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Beulich @ 2014-09-09 14:36 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

>>> On 09.09.14 at 16:21, <daniel.kiper@oracle.com> wrote:
> On Mon, Aug 11, 2014 at 11:33:32AM +0100, Jan Beulich wrote:
>> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
>> > +
>> > +        /*
>> > +         * Align Xen image and modules at page boundry.
>> > +         *
>> > +         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
>> > +         * to avoid bug related to Multiboot2 information request tag in earlier
>> > +         * versions of GRUB2.
>> > +         *
>> > +         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
>> > +         * WITH EARLIER GRUB2 VERSIONS!
>> > +         */
>>
>> Question is - since your ultimate goal of getting UEFI to work this way
>> won't be achievable with older GrUB2 anyway, do we care at all? Also,
> 
> I think that it makes sense to have multiboot2 protocol implementation
> working on every GRUB2 version. This way it will be quite easy to use
> that same Xen image regardless of GRUB and multiboot protocol version.
> Additionally, I discovered that above mentioned bug depends on 
> multiboot2_info_req
> contents which is very annoying and not very easy to discover. So, this
> hack ensures that regardless of multiboot2_info_req contents Xen image
> behaves always in the same way on every GRUB2 version (with or without bug).

I'm still not convinced that adding hacks for something that won't work
right anyway is useful.

>> > @@ -81,10 +144,55 @@ __start:
>> >          mov     %ecx,%es
>> >          mov     %ecx,%ss
>> >
>> > +        /* Set mem_lower to 0 */
>> > +        xor     %edx,%edx
>> > +
>> >          /* Check for Multiboot bootloader */
>> > -        cmp     $0x2BADB002,%eax
>> > -        jne     not_multiboot
>> > +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
>> > +        je      1f
>> > +
>> > +        /* Check for Multiboot2 bootloader */
>> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
>> > +        je      2f
>> > +
>> > +        jmp     not_multiboot
>> > +
>> > +1:
>> > +        /* Get mem_lower from Multiboot information */
>> > +        testb   $MBI_MEMLIMITS,(%ebx)
>> > +        jz      0f                  /* not available? BDA value will be fine */
>> >
>> > +        mov     4(%ebx),%edx
>> > +        shl     $10-4,%edx
>> > +        jmp     0f
>>
>> This code isn't being moved here from elsewhere, but also isn't
>> multiboot2 related - what's this about? If it's really needed for
>> something, this should be in a separate patch imo.
> 
> Here we are reading data from multiboot[1] protocol. Label
> below is start of multiboot2 protocol implementation. We
> need rearrange a bit multiboot[1] protocol implementation
> to have both protocols working.

Re-arrange to me means the same code was present elsewhere
before. But as said in my initial reply, I can't spot any such origin.

>> > --- a/xen/arch/x86/boot/reloc.c
>> > +++ b/xen/arch/x86/boot/reloc.c
>> > @@ -18,8 +18,12 @@ typedef unsigned long u32;
>> >  typedef unsigned long long u64;
>> >
>> >  #include "../../../include/xen/multiboot.h"
>> > +#include "../../../include/xen/multiboot2.h"
>> >  #include "../../../include/asm/mbd.h"
>> >
>> > +#define ALIGN_UP(addr, align) \
>> > +                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align - 
> 1))
>>
>> Even if just used locally, please make sure such macros are properly
>> parenthesized.
> 
> You mean?

Which part is unclear here? Macro arguments used in expressions
should be parenthesized.

>> > +        case MULTIBOOT2_TAG_TYPE_MMAP:
>> > +            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
>> > +            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
>> > +            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
>> > +            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
>> > +            mbd->mmap_size *= sizeof(memory_map_t);
>> > +
>> > +            mbd->mmap = alloc_struct(mbd->mmap_size);
>> > +
>> > +            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
>> > +            mmap_dst = (memory_map_t *)mbd->mmap;
>> > +
>> > +            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)
>>
>> Coding style.
> 
> You mean?

You're kidding, aren't you? I think by now you should not require
help with seeing where your "for" above lacks blanks.

Jan

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 1/7] xen/x86: Add mbd.h header file
  2014-09-09 14:28       ` Jan Beulich
@ 2014-09-09 15:57         ` Daniel Kiper
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 15:57 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Tue, Sep 09, 2014 at 03:28:27PM +0100, Jan Beulich wrote:
> >>> On 09.09.14 at 15:39, <daniel.kiper@oracle.com> wrote:
> > On Mon, Aug 11, 2014 at 10:49:15AM +0100, Jan Beulich wrote:
> >> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> >> > --- /dev/null
> >> > +++ b/xen/include/asm-x86/mbd.h
> >> > @@ -0,0 +1,70 @@
> >> > +/*
> >> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> >> > + *
> >> > + * This program is free software; you can redistribute it and/or modify
> >> > + * it under the terms of the GNU General Public License as published by
> >> > + * the Free Software Foundation; either version 2 of the License, or
> >> > + * (at your option) any later version.
> >> > + *
> >> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> >> > + */
> >> > +
> >> > +#ifndef __MBD_H__
> >> > +#define __MBD_H__
> >> > +
> >> > +/* Module type. */
> >> > +typedef struct {
> >> > +    u32 start;
> >> > +    u32 end;
> >> > +
> >> > +    /* Pointer to a module command line. */
> >> > +    u32 cmdline;
> >> > +
> >> > +    /* If relocated != 0 then a given module was relocated. */
> >> > +    u32 relocated;
> >> > +} boot_module_t;
> >> > +
> >> > +/*
> >> > + * MultiBoot Data (MBD) type. It is used to define variable which
> >> > + * carry over data from multiboot protocol (any version) through
> >> > + * Xen preloader stage. Later all or parts of this data is used
> >> > + * to initialize Xen Boot Info (XBI) structure.
> >> > + */
> >> > +typedef struct {
> >> > +    /* Pointer to boot loader name. */
> >> > +    u32 boot_loader_name;
> >> > +
> >> > +    /* Pointer to Xen command line. */
> >> > +    u32 cmdline;
> >> > +
> >> > +    /*
> >> > +     * Amount of lower memory (in KiB) accordingly to The Multiboot
> >> > +     * Specification version 0.6.96.
> >> > +     */
> >> > +    u32 mem_lower;
> >> > +
> >> > +    /*
> >> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> >> > +     * Specification version 0.6.96.
> >> > +     */
> >> > +    u32 mem_upper;
> >> > +
> >> > +    /* Size (in bytes) of memory map provided by bootloader. */
> >> > +    u32 mmap_size;
> >> > +
> >> > +    /* Pointer to memory map provided by bootloader. */
> >> > +    u32 mmap;
> >> > +
> >> > +    /* Number of modules. */
> >> > +    u32 mods_nr;
> >> > +
> >> > +    /* Pointer to modules description (boot_module_t *). */
> >> > +    u32 mods;
> >> > +} mbd_t;
> >> > +#endif /* __MBD_H__ */
> >>
> >> For several of the fields I wonder whether u32 is really the right
> >> data type (i.e. whether u64 wouldn't be more correct going
> >> forward).
> >
> > All data which we get from multiboot[12] is u32. So, I think it does not
> > make sense to use u64 here.
>
> Wasn't your proposal to make this an abstraction? If so, what
> does the (current) data source have to do with the types here?

No, this structure is used to transport multiboot[12] protocol
data through preloader stage. It is x86 internal stuff. Later,
all boot data from various sources (including MBD) is put into
XBI. So, probably you think about XBI. This struct will be common
stuff for archs. Hence, in case of XBI I agree that we should very
carefully choose relevant types.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support
  2014-09-09 14:36       ` Jan Beulich
@ 2014-09-09 16:04         ` Daniel Kiper
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-09-09 16:04 UTC (permalink / raw)
  To: Jan Beulich
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	ross.philipson, xen-devel, qiaowei.ren, richard.l.maliszewski,
	gang.wei, fu.wei

On Tue, Sep 09, 2014 at 03:36:44PM +0100, Jan Beulich wrote:
> >>> On 09.09.14 at 16:21, <daniel.kiper@oracle.com> wrote:
> > On Mon, Aug 11, 2014 at 11:33:32AM +0100, Jan Beulich wrote:
> >> >>> On 09.08.14 at 01:04, <daniel.kiper@oracle.com> wrote:
> >> > +
> >> > +        /*
> >> > +         * Align Xen image and modules at page boundry.
> >> > +         *
> >> > +         * .balignl MULTIBOOT2_TAG_ALIGN, MULTIBOOT2_TAG_TYPE_END is a hack
> >> > +         * to avoid bug related to Multiboot2 information request tag in earlier
> >> > +         * versions of GRUB2.
> >> > +         *
> >> > +         * DO NOT MOVE THIS TAG! ANY CHANGE HERE MAY BREAK COMPATIBILITY
> >> > +         * WITH EARLIER GRUB2 VERSIONS!
> >> > +         */
> >>
> >> Question is - since your ultimate goal of getting UEFI to work this way
> >> won't be achievable with older GrUB2 anyway, do we care at all? Also,
> >
> > I think that it makes sense to have multiboot2 protocol implementation
> > working on every GRUB2 version. This way it will be quite easy to use
> > that same Xen image regardless of GRUB and multiboot protocol version.
> > Additionally, I discovered that above mentioned bug depends on
> > multiboot2_info_req
> > contents which is very annoying and not very easy to discover. So, this
> > hack ensures that regardless of multiboot2_info_req contents Xen image
> > behaves always in the same way on every GRUB2 version (with or without bug).
>
> I'm still not convinced that adding hacks for something that won't work
> right anyway is useful.
>
> >> > @@ -81,10 +144,55 @@ __start:
> >> >          mov     %ecx,%es
> >> >          mov     %ecx,%ss
> >> >
> >> > +        /* Set mem_lower to 0 */
> >> > +        xor     %edx,%edx
> >> > +
> >> >          /* Check for Multiboot bootloader */
> >> > -        cmp     $0x2BADB002,%eax
> >> > -        jne     not_multiboot
> >> > +        cmp     $MULTIBOOT_BOOTLOADER_MAGIC,%eax
> >> > +        je      1f
> >> > +
> >> > +        /* Check for Multiboot2 bootloader */
> >> > +        cmp     $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
> >> > +        je      2f
> >> > +
> >> > +        jmp     not_multiboot
> >> > +
> >> > +1:
> >> > +        /* Get mem_lower from Multiboot information */
> >> > +        testb   $MBI_MEMLIMITS,(%ebx)
> >> > +        jz      0f                  /* not available? BDA value will be fine */
> >> >
> >> > +        mov     4(%ebx),%edx
> >> > +        shl     $10-4,%edx
> >> > +        jmp     0f
> >>
> >> This code isn't being moved here from elsewhere, but also isn't
> >> multiboot2 related - what's this about? If it's really needed for
> >> something, this should be in a separate patch imo.
> >
> > Here we are reading data from multiboot[1] protocol. Label
> > below is start of multiboot2 protocol implementation. We
> > need rearrange a bit multiboot[1] protocol implementation
> > to have both protocols working.
>
> Re-arrange to me means the same code was present elsewhere
> before. But as said in my initial reply, I can't spot any such origin.

Ahhh... I have just spotted that. I forgot to remove relevant code a few
lines below. Thanks.

> >> > --- a/xen/arch/x86/boot/reloc.c
> >> > +++ b/xen/arch/x86/boot/reloc.c
> >> > @@ -18,8 +18,12 @@ typedef unsigned long u32;
> >> >  typedef unsigned long long u64;
> >> >
> >> >  #include "../../../include/xen/multiboot.h"
> >> > +#include "../../../include/xen/multiboot2.h"
> >> >  #include "../../../include/asm/mbd.h"
> >> >
> >> > +#define ALIGN_UP(addr, align) \
> >> > +                ((addr + (typeof(addr))align - 1) & ~((typeof(addr))align -
> > 1))
> >>
> >> Even if just used locally, please make sure such macros are properly
> >> parenthesized.
> >
> > You mean?
>
> Which part is unclear here? Macro arguments used in expressions
> should be parenthesized.

Too fast reading. I have missed that.

> >> > +        case MULTIBOOT2_TAG_TYPE_MMAP:
> >> > +            mbd->mmap_size = ((multiboot2_tag_mmap_t *)tag)->size;
> >> > +            mbd->mmap_size -= sizeof(multiboot2_tag_mmap_t);
> >> > +            mbd->mmap_size += sizeof(((multiboot2_tag_mmap_t){0}).entries);
> >> > +            mbd->mmap_size /= ((multiboot2_tag_mmap_t *)tag)->entry_size;
> >> > +            mbd->mmap_size *= sizeof(memory_map_t);
> >> > +
> >> > +            mbd->mmap = alloc_struct(mbd->mmap_size);
> >> > +
> >> > +            mmap_src = ((multiboot2_tag_mmap_t *)tag)->entries;
> >> > +            mmap_dst = (memory_map_t *)mbd->mmap;
> >> > +
> >> > +            for (i = 0; i < mbd->mmap_size / sizeof(memory_map_t); ++i)
> >>
> >> Coding style.
> >
> > You mean?
>
> You're kidding, aren't you? I think by now you should not require
> help with seeing where your "for" above lacks blanks.

Ditto.

Thanks,

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-08-10 16:34   ` Andrew Cooper
@ 2014-09-18 16:30     ` Daniel Kiper
  2014-09-19  6:46       ` Jan Beulich
  0 siblings, 1 reply; 40+ messages in thread
From: Daniel Kiper @ 2014-09-18 16:30 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: keir, ian.campbell, stefano.stabellini, roy.franz, ning.sun,
	jbeulich, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

On Sun, Aug 10, 2014 at 05:34:11PM +0100, Andrew Cooper wrote:
> On 09/08/14 00:04, Daniel Kiper wrote:
> > Define Xen Boot Info (XBI) type. This will be used to define variable
> > used to store data collected by bootloader and preloader. This way
> > we are able to make most of Xen code bootloader agnostic.
> >
> > Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
>
> This looks ok in principle, and the end goal seems like a good idea.
>
> > ---
> >  xen/include/asm-x86/xbi.h |  117 +++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 117 insertions(+)
> >  create mode 100644 xen/include/asm-x86/xbi.h
> >
> > diff --git a/xen/include/asm-x86/xbi.h b/xen/include/asm-x86/xbi.h
> > new file mode 100644
> > index 0000000..ca9e615
> > --- /dev/null
> > +++ b/xen/include/asm-x86/xbi.h
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Copyright (c) 2013, 2014 Oracle Co., Daniel Kiper
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that 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, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#ifndef __XBI_H__
> > +#define __XBI_H__
> > +
> > +#include <xen/types.h>
> > +#include <xen/vga.h>
> > +
> > +#include <asm/e820.h>
> > +#include <asm/edd.h>
> > +#include <asm/mbd.h>
> > +
> > +/* Xen Boot Info (XBI) type. */
>
> Probably need a rather larger comment here, reiterating that this
> structure is a collection of information provided/found by the
> bootloader/preloader, and presented in a common place for the Xen boot code.
>
> > +typedef struct {
> > +    /* Boot loader name. */
> > +    char *boot_loader_name;
> > +
> > +    /* Xen command line. */
> > +    char *cmdline;
> > +
> > +    /* Memory map type (source of memory map). */
> > +    char *mmap_type;
> > +
> > +    /*
> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
> > +     * Specification version 0.6.96.
> > +     */
> > +    u32 mem_upper;
> > +
> > +    /* Number of memory map entries provided by Xen preloader. */
> > +    int e820map_nr;
>
> Count of e820 entries is inherently an unsigned quantity.

OK, but after some investigation it looks that we should change also
xen/arch/x86/e820.c:init_e820() and friends due to type signedness
conflicts. I think that this is good idea but I would like to ask
you guys about your opinion. So?

> > +    /*
> > +     * Memory map provided by Xen preloader. It should always point
> > +     * to an area able to accommodate at least E820MAX entries.
> > +     */
> > +    struct e820entry *e820map;
> > +
> > +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
> > +    unsigned long efi_mmap_size;
> > +
> > +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
> > +    unsigned long efi_mmap_desc_size;
>
> size_t for these two?

Both of them should be UINTN because they are referenced
from EFI function GetMemoryMap(). However, this means that
we must include asm/efibind.h and efi/efidef.h. If we do
that then:

In file included from xen/include/acpi/acpi.h:57:0,
                 from xen/include/xen/acpi.h:34,
                 from xen/include/asm/boot_info.h:25,
                 from boot.c:27:
xen/include/acpi/actypes.h:130:35: error: conflicting types for ‘UINT64’

and

In file included from xen/include/acpi/acpi.h:57:0,
                 from xen/include/xen/acpi.h:34,
                 from xen/include/asm/boot_info.h:25,
                 from boot.c:27:
xen/include/acpi/actypes.h:131:34: error: conflicting types for ‘INT64’

That is why I used unsigned long here. It is a hack to avoid that issue.
I forgot about that. However, now if we wish to proceed further we should
do something with this conflict. Avoidance is not a solution in that case
because if we do that right now then this conflict will hit us once again
sooner or later somewhere else. So, I think that we should rename all
basic EFI types and use EFI_ prefix, e.g., EFI_UINT64. This way we will
avoid this conflict with ACPI types in the future. What do you think
about that? Do you have better solution for that problem?

> > +    /* Pointer to EFI memory map provided by preloader. */
> > +    void *efi_mmap;

EFI_MEMORY_DESCRIPTOR *efi_mmap;

That is why we need efi/efidef.h too.

> > +
> > +    /* Pointer to MPS. */
> > +    unsigned long mps;

paddr_t mps;

> > +    /* Pointer to ACPI RSDP. */
> > +    unsigned long acpi;

acpi_physical_address acpi;

...but #include <xen/acpi.h> generates conflict with
EFI types similar to mentioned above...

> > +    /* Pointer to ACPI 2.0 RSDP. */
> > +    unsigned long acpi20;

acpi_physical_address acpi20;

...but #include <xen/acpi.h> generates conflict with
EFI types similar to mentioned above...

> > +    /* Pointer to SMBIOS. */
> > +    unsigned long smbios;

paddr_t smbios;

> I presume these 4 are all physical addresses?  how about paddr_t ?
>
> > +
> > +    /* Pointer to EFI System Table. */
> > +    void *efi_system_table;

EFI_SYSTEM_TABLE *efi_system_table;

...but conflict with ACPI types as above...

Daniel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 2/7] xen/x86: Add xbi.h header file
  2014-09-18 16:30     ` Daniel Kiper
@ 2014-09-19  6:46       ` Jan Beulich
  0 siblings, 0 replies; 40+ messages in thread
From: Jan Beulich @ 2014-09-19  6:46 UTC (permalink / raw)
  To: Daniel Kiper
  Cc: keir, ian.campbell, stefano.stabellini, Andrew Cooper, roy.franz,
	ning.sun, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

>>> On 18.09.14 at 18:30, <daniel.kiper@oracle.com> wrote:
> On Sun, Aug 10, 2014 at 05:34:11PM +0100, Andrew Cooper wrote:
>> On 09/08/14 00:04, Daniel Kiper wrote:
>> > +typedef struct {
>> > +    /* Boot loader name. */
>> > +    char *boot_loader_name;
>> > +
>> > +    /* Xen command line. */
>> > +    char *cmdline;
>> > +
>> > +    /* Memory map type (source of memory map). */
>> > +    char *mmap_type;
>> > +
>> > +    /*
>> > +     * Amount of upper memory (in KiB) accordingly to The Multiboot
>> > +     * Specification version 0.6.96.
>> > +     */
>> > +    u32 mem_upper;
>> > +
>> > +    /* Number of memory map entries provided by Xen preloader. */
>> > +    int e820map_nr;
>>
>> Count of e820 entries is inherently an unsigned quantity.
> 
> OK, but after some investigation it looks that we should change also
> xen/arch/x86/e820.c:init_e820() and friends due to type signedness
> conflicts. I think that this is good idea but I would like to ask
> you guys about your opinion. So?

The general direction here is to not let new code in that's not
sufficiently sign- or const-correct, but not bother cleaning up
old code unless touching it anyway. But if you feel like submitting
a patch correcting signedness there, just go ahead.

>> > +    /*
>> > +     * Memory map provided by Xen preloader. It should always point
>> > +     * to an area able to accommodate at least E820MAX entries.
>> > +     */
>> > +    struct e820entry *e820map;
>> > +
>> > +    /* Size (in bytes) of EFI memory map provided by Xen preloader. */
>> > +    unsigned long efi_mmap_size;
>> > +
>> > +    /* Size (in bytes) of EFI memory map descriptor provided by Xen preloader. */
>> > +    unsigned long efi_mmap_desc_size;
>>
>> size_t for these two?
> 
> Both of them should be UINTN because they are referenced
> from EFI function GetMemoryMap(). However, this means that
> we must include asm/efibind.h and efi/efidef.h. If we do
> that then:
> 
> In file included from xen/include/acpi/acpi.h:57:0,
>                  from xen/include/xen/acpi.h:34,
>                  from xen/include/asm/boot_info.h:25,
>                  from boot.c:27:
> xen/include/acpi/actypes.h:130:35: error: conflicting types for ‘UINT64’
> 
> and
> 
> In file included from xen/include/acpi/acpi.h:57:0,
>                  from xen/include/xen/acpi.h:34,
>                  from xen/include/asm/boot_info.h:25,
>                  from boot.c:27:
> xen/include/acpi/actypes.h:131:34: error: conflicting types for ‘INT64’
> 
> That is why I used unsigned long here. It is a hack to avoid that issue.
> I forgot about that. However, now if we wish to proceed further we should
> do something with this conflict. Avoidance is not a solution in that case
> because if we do that right now then this conflict will hit us once again
> sooner or later somewhere else. So, I think that we should rename all
> basic EFI types and use EFI_ prefix, e.g., EFI_UINT64. This way we will
> avoid this conflict with ACPI types in the future. What do you think
> about that?

Absolutely not - these headers should stay as closely in sync with
their originals as possible to ease eventual updating.

> Do you have better solution for that problem?

Don't include ACPI and EFI headers at the same time, or use
compatible types (as you did, and as - I think - size_t would also
do). In the latter case a comment explaining why the original
types can't be used would perhaps avoid questions like Andrew's.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH RFC 4/7] xen/x86: Migrate to XBI structure
@ 2014-08-13 13:53 Daniel Kiper
  0 siblings, 0 replies; 40+ messages in thread
From: Daniel Kiper @ 2014-08-13 13:53 UTC (permalink / raw)
  To: jbeulich
  Cc: keir, ian.campbell, stefano.stabellini, andrew.cooper3,
	roy.franz, ning.sun, ross.philipson, xen-devel, qiaowei.ren,
	richard.l.maliszewski, gang.wei, fu.wei

Hi all,

> >>> On 10.08.14 at 19:05, <andrew.cooper3@citrix.com> wrote:
> > This patch is massive, and really needs splitting up somewhat.  There
> > are several logically distinct bits to it.
>
> +1 - I think I'll not even spend much time looking at the patch without
> it being split up. The splitting is being done quite inconsistently anyway:
> The first 3 patches were headers without users, and now we get this
> extremely massive single patch.

Thanks for your comments guys. I am happy that you
accepted my idea in general. I will continue work
on this when I will be back home, i.e. more or less
at the beginning of September. However, I am also
happy to discuss the details in Chicago next week.

Daniel

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2014-09-19  6:46 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-08 23:03 [PATCH RFC 0/7] xen: Break multiboot (v1) dependency and add multiboot2 support Daniel Kiper
2014-08-08 23:04 ` [PATCH RFC 1/7] xen/x86: Add mbd.h header file Daniel Kiper
2014-08-11  9:49   ` Jan Beulich
2014-08-11 16:16     ` Stefano Stabellini
2014-09-03 14:11       ` Ian Campbell
2014-09-03 15:16         ` Daniel Kiper
2014-09-04 22:45           ` Stefano Stabellini
2014-09-09 13:39     ` Daniel Kiper
2014-09-09 14:28       ` Jan Beulich
2014-09-09 15:57         ` Daniel Kiper
2014-08-08 23:04 ` [PATCH RFC 2/7] xen/x86: Add xbi.h " Daniel Kiper
2014-08-10 16:34   ` Andrew Cooper
2014-09-18 16:30     ` Daniel Kiper
2014-09-19  6:46       ` Jan Beulich
2014-08-11  9:54   ` Jan Beulich
2014-08-11 16:20   ` Stefano Stabellini
2014-08-11 16:37     ` Stefano Stabellini
2014-08-08 23:04 ` [PATCH RFC 3/7] xen: Add multiboot2.h " Daniel Kiper
2014-08-11  9:58   ` Jan Beulich
2014-09-09 13:47     ` Daniel Kiper
2014-08-08 23:04 ` [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper
2014-08-09  0:07   ` Roy Franz
2014-08-10 16:22     ` Daniel Kiper
2014-08-10 17:05   ` Andrew Cooper
2014-08-11 10:01     ` Jan Beulich
2014-09-09 13:22     ` Daniel Kiper
2014-09-09 13:37       ` Jan Beulich
2014-09-09 13:39       ` Andrew Cooper
2014-08-08 23:04 ` [PATCH RFC 5/7] xen/x86: Add multiboot2 protocol support Daniel Kiper
2014-08-10 17:23   ` Andrew Cooper
2014-09-09 13:34     ` Daniel Kiper
2014-09-09 13:43       ` Andrew Cooper
2014-08-11 10:33   ` Jan Beulich
2014-09-09 14:21     ` Daniel Kiper
2014-09-09 14:36       ` Jan Beulich
2014-09-09 16:04         ` Daniel Kiper
2014-08-08 23:04 ` [PATCH RFC 6/7] xen: Remove redundant xen/include/xen/vga.h file Daniel Kiper
2014-08-11 10:35   ` Jan Beulich
2014-08-08 23:04 ` [PATCH RFC 7/7] xen/x86: Add new line to the end of graphics mode error message Daniel Kiper
2014-08-13 13:53 [PATCH RFC 4/7] xen/x86: Migrate to XBI structure Daniel Kiper

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.