[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 4/8] xen: add xen pvh guest support to grub-core



Add all the grub-core code needed for Xen PVH guest support. This
includes:

- The new PVH entry point of grub
- PVH specific initialization code
- machine specific header files
- modifications in Xen specific code to work in PVH environment
- modifications in other core code to be reusable with PVH

Enabling all this code is done later.

Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
 grub-core/kern/i386/tsc.c             |   2 +-
 grub-core/kern/i386/xen/pvh.c         | 344 ++++++++++++++++++++++++++++++++++
 grub-core/kern/i386/xen/startup_pvh.S |  80 ++++++++
 grub-core/kern/xen/init.c             |  66 ++++---
 include/grub/i386/pc/int.h            |   3 +
 include/grub/i386/tsc.h               |   2 +-
 include/grub/i386/xen/hypercall.h     |   5 +-
 include/grub/i386/xenpvh/boot.h       |   1 +
 include/grub/i386/xenpvh/console.h    |   1 +
 include/grub/i386/xenpvh/int.h        |   1 +
 include/grub/i386/xenpvh/kernel.h     |  30 +++
 include/grub/i386/xenpvh/memory.h     |  54 ++++++
 include/grub/i386/xenpvh/time.h       |   1 +
 include/grub/kernel.h                 |   4 +-
 include/grub/offsets.h                |   3 +
 include/grub/xen.h                    |   6 +
 16 files changed, 573 insertions(+), 30 deletions(-)
 create mode 100644 grub-core/kern/i386/xen/pvh.c
 create mode 100644 grub-core/kern/i386/xen/startup_pvh.S
 create mode 100644 include/grub/i386/xenpvh/boot.h
 create mode 100644 include/grub/i386/xenpvh/console.h
 create mode 100644 include/grub/i386/xenpvh/int.h
 create mode 100644 include/grub/i386/xenpvh/kernel.h
 create mode 100644 include/grub/i386/xenpvh/memory.h
 create mode 100644 include/grub/i386/xenpvh/time.h

diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c
index f266eb131..43fee3a13 100644
--- a/grub-core/kern/i386/tsc.c
+++ b/grub-core/kern/i386/tsc.c
@@ -65,7 +65,7 @@ grub_tsc_init (void)
 
   tsc_boot_time = grub_get_tsc ();
 
-#ifdef GRUB_MACHINE_XEN
+#if defined (GRUB_MACHINE_XEN) || defined (GRUB_MACHINE_XENPVH)
   (void) (grub_tsc_calibrate_from_xen () || calibrate_tsc_hardcode());
 #elif defined (GRUB_MACHINE_EFI)
   (void) (grub_tsc_calibrate_from_pmtimer () || grub_tsc_calibrate_from_pit () 
|| grub_tsc_calibrate_from_efi() || calibrate_tsc_hardcode());
diff --git a/grub-core/kern/i386/xen/pvh.c b/grub-core/kern/i386/xen/pvh.c
new file mode 100644
index 000000000..6f154d176
--- /dev/null
+++ b/grub-core/kern/i386/xen/pvh.c
@@ -0,0 +1,344 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2011  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/i386/cpuid.h>
+#include <grub/xen.h>
+#include <grub/i386/linux.h>
+#include <grub/machine/kernel.h>
+#include <xen/hvm/params.h>
+#include <xen/memory.h>
+
+struct xen_machine_mmap_entry
+{
+  grub_uint64_t addr;
+  grub_uint64_t len;
+  grub_uint32_t type;
+} GRUB_PACKED;
+
+grub_uint64_t grub_rsdp_addr;
+
+static struct { char _entry[32]; } hypercall_page[128]
+  __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+static grub_uint32_t xen_cpuid_base;
+static struct start_info grub_xen_start_page;
+static struct xen_machine_mmap_entry map[128];
+static unsigned int nr_map_entries;
+
+static void
+grub_xen_early_halt (void)
+{
+  asm volatile ("hlt");
+}
+
+static void
+grub_xen_cpuid_base (void)
+{
+  grub_uint32_t base, eax, signature[3];
+
+  for (base = 0x40000000; base < 0x40010000; base += 0x100)
+    {
+      grub_cpuid (base, eax, signature[0], signature[1], signature[2]);
+      if (!grub_memcmp ("XenVMMXenVMM", signature, 12) && (eax - base) >= 2)
+        {
+          xen_cpuid_base = base;
+          return;
+        }
+    }
+
+  grub_xen_early_halt ();
+}
+
+static void
+grub_xen_setup_hypercall_page (void)
+{
+  grub_uint32_t msr, pfn, eax, ebx, ecx, edx;
+
+  grub_cpuid (xen_cpuid_base + 2, eax, ebx, ecx, edx);
+  msr = ebx;
+  pfn = (grub_uint32_t) (&hypercall_page[0]);
+
+  asm volatile ("wrmsr" : : "c" (msr), "a" (pfn), "d" (0) : "memory");
+}
+
+int
+grub_xen_hypercall (grub_uint32_t callno, grub_uint32_t a0,
+                   grub_uint32_t a1, grub_uint32_t a2,
+                   grub_uint32_t a3, grub_uint32_t a4,
+                   grub_uint32_t a5 __attribute__ ((unused)))
+{
+  register unsigned long __res  asm("eax");
+  register unsigned long __arg0 asm("ebx") = __arg0;
+  register unsigned long __arg1 asm("ecx") = __arg1;
+  register unsigned long __arg2 asm("edx") = __arg2;
+  register unsigned long __arg3 asm("esi") = __arg3;
+  register unsigned long __arg4 asm("edi") = __arg4;
+
+  __arg0 = a0;
+  __arg1 = a1;
+  __arg2 = a2;
+  __arg3 = a3;
+  __arg4 = a4;
+  asm volatile ("call *%[callno]"
+               : "=r" (__res), "+r" (__arg0), "+r" (__arg1), "+r" (__arg2),
+                 "+r" (__arg3), "+r" (__arg4)
+               : [callno] "a" (&hypercall_page[callno])
+               : "memory");
+  return __res;
+}
+
+static grub_uint32_t
+grub_xen_get_param (int idx)
+{
+  struct xen_hvm_param xhv;
+  int r;
+
+  xhv.domid = DOMID_SELF;
+  xhv.index = idx;
+  r = grub_xen_hypercall (__HYPERVISOR_hvm_op, HVMOP_get_param,
+                         (grub_uint32_t) (&xhv), 0, 0, 0, 0);
+  if (r < 0)
+    grub_xen_early_halt ();
+  return xhv.value;
+}
+
+static void *
+grub_xen_add_physmap (unsigned int space, void *addr)
+{
+  struct xen_add_to_physmap xatp;
+
+  xatp.domid = DOMID_SELF;
+  xatp.idx = 0;
+  xatp.space = space;
+  xatp.gpfn = (grub_addr_t) addr >> GRUB_XEN_LOG_PAGE_SIZE;
+  if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_add_to_physmap,
+                         (grub_uint32_t) (&xatp), 0, 0, 0, 0))
+    grub_xen_early_halt ();
+  return addr;
+}
+
+static void
+grub_xen_sort_mmap (void)
+{
+  grub_addr_t from, to;
+  unsigned int i;
+  struct xen_machine_mmap_entry tmp;
+
+  /* Align map entries to page boundaries. */
+  for (i = 0; i < nr_map_entries; i++)
+    {
+      from = map[i].addr;
+      to = from + map[i].len;
+      if (map[i].type == GRUB_MEMORY_AVAILABLE)
+       {
+         from = ALIGN_UP(from, GRUB_XEN_PAGE_SIZE);
+         to = ALIGN_DOWN(to, GRUB_XEN_PAGE_SIZE);
+       }
+      else
+       {
+         from = ALIGN_DOWN(from, GRUB_XEN_PAGE_SIZE);
+         to = ALIGN_UP(to, GRUB_XEN_PAGE_SIZE);
+       }
+      map[i].addr = from;
+      map[i].len = to - from;
+    }
+
+ again:
+  /* Sort entries by start address. */
+  for (i = 1; i < nr_map_entries; i++)
+    {
+      if (map[i].addr >= map[i - 1].addr)
+       continue;
+      tmp = map[i];
+      map[i] = map[i - 1];
+      map[i - 1] = tmp;
+      i = 0;
+    }
+
+  /* Detect overlapping areas. */
+  for (i = 1; i < nr_map_entries; i++)
+    {
+      if (map[i].addr >= map[i - 1].addr + map[i - 1].len)
+       continue;
+      tmp = map[i - 1];
+      map[i - 1].len = map[i].addr - map[i - 1].addr;
+      if (map[i].addr + map[i].len >= tmp.addr + tmp.len)
+       continue;
+      if (nr_map_entries < ARRAY_SIZE(map))
+       {
+         map[nr_map_entries].addr = map[i].addr + map[i].len;
+         map[nr_map_entries].len = tmp.addr + tmp.len - 
map[nr_map_entries].addr;
+         map[nr_map_entries].type = tmp.type;
+         nr_map_entries++;
+         goto again;
+       }
+    }
+
+  /* Merge adjacent entries. */
+  for (i = 1; i < nr_map_entries; i++)
+    {
+      if (map[i].type == map[i - 1].type &&
+         map[i].addr == map[i - 1].addr + map[i - 1].len)
+       {
+         map[i - 1].len += map[i].len;
+         map[i] = map[nr_map_entries - 1];
+         nr_map_entries--;
+         goto again;
+       }
+    }
+}
+
+static void
+grub_xen_get_mmap (void)
+{
+  struct xen_memory_map memmap;
+
+  memmap.nr_entries = ARRAY_SIZE(map);
+  set_xen_guest_handle (memmap.buffer, map);
+  if (grub_xen_hypercall (__HYPERVISOR_memory_op, XENMEM_memory_map,
+                         (grub_uint32_t) (&memmap), 0, 0, 0, 0))
+    grub_xen_early_halt ();
+  nr_map_entries = memmap.nr_entries;
+
+  grub_xen_sort_mmap ();
+}
+
+static void
+grub_xen_mm_init_regions (void)
+{
+  grub_addr_t modend, from, to;
+  unsigned int i;
+
+  modend = grub_modules_get_end ();
+
+  for (i = 0; i < nr_map_entries; i++)
+    {
+      if (map[i].type != GRUB_MEMORY_AVAILABLE)
+        continue;
+      from = map[i].addr;
+      to = from + map[i].len;
+      if (from < modend)
+        from = modend;
+      if (from >= to)
+        continue;
+      grub_mm_init_region ((void *) from, to - from);
+    }
+}
+
+static grub_addr_t
+grub_xen_find_page (grub_addr_t start)
+{
+  unsigned int i, j;
+  grub_addr_t last = start;
+
+  /* Try to find a e820 map hole below 4G. */
+  for (i = 0; i < nr_map_entries; i++)
+    {
+      if (last > map[i].addr + map[i].len)
+       continue;
+      if (last < map[i].addr)
+       return last;
+      if ((map[i].addr >> 32) || ((map[i].addr + map[i].len) >> 32))
+       break;
+      last = map[i].addr + map[i].len;
+    }
+    if (i == nr_map_entries)
+      return last;
+
+  /* No hole found, use the highest RAM page below 4G and reserve it. */
+  if (nr_map_entries == ARRAY_SIZE(map))
+    grub_xen_early_halt ();
+  j = 0;
+  for (i = 0; i < nr_map_entries; i++)
+    {
+      if (map[i].type != GRUB_MEMORY_AVAILABLE)
+       continue;
+      if (map[i].addr >> 32)
+       break;
+      j = i;
+      if ((map[i].addr + map[i].len) >> 32)
+       break;
+    }
+  if (map[j].type != GRUB_MEMORY_AVAILABLE)
+    grub_xen_early_halt ();
+  if ((map[i].addr + map[i].len) >> 32)
+    last = (1ULL << 32) - GRUB_XEN_PAGE_SIZE;
+  else
+    last = map[i].addr + map[i].len - GRUB_XEN_PAGE_SIZE;
+  map[nr_map_entries].addr = last;
+  map[nr_map_entries].len = GRUB_XEN_PAGE_SIZE;
+  map[nr_map_entries].type = GRUB_MEMORY_RESERVED;
+  nr_map_entries++;
+  grub_xen_sort_mmap ();
+
+  return last;
+}
+
+void
+grub_xen_setup_pvh (void)
+{
+  grub_addr_t par;
+
+  grub_xen_cpuid_base ();
+  grub_xen_setup_hypercall_page ();
+  grub_xen_get_mmap ();
+
+  /* Setup Xen data. */
+  grub_xen_start_page_addr = &grub_xen_start_page;
+
+  par = grub_xen_get_param (HVM_PARAM_CONSOLE_PFN);
+  grub_xen_start_page_addr->console.domU.mfn = par;
+  grub_xen_xcons = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
+  par = grub_xen_get_param (HVM_PARAM_CONSOLE_EVTCHN);
+  grub_xen_start_page_addr->console.domU.evtchn = par;
+
+  par = grub_xen_get_param (HVM_PARAM_STORE_PFN);
+  grub_xen_start_page_addr->store_mfn = par;
+  grub_xen_xenstore = (void *) (grub_addr_t) (par << GRUB_XEN_LOG_PAGE_SIZE);
+  par = grub_xen_get_param (HVM_PARAM_STORE_EVTCHN);
+  grub_xen_start_page_addr->store_evtchn = par;
+
+  par = grub_xen_find_page (0);
+  grub_xen_grant_table = grub_xen_add_physmap (XENMAPSPACE_grant_table,
+                                              (void *) par);
+  par = grub_xen_find_page (par + GRUB_XEN_PAGE_SIZE);
+  grub_xen_shared_info = grub_xen_add_physmap (XENMAPSPACE_shared_info,
+                                              (void *) par);
+
+  grub_xen_mm_init_regions ();
+
+  grub_rsdp_addr = pvh_start_info->rsdp_paddr;
+}
+
+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+  unsigned int i;
+
+  for (i = 0; i < nr_map_entries; i++)
+    {
+      if (map[i].len && hook (map[i].addr, map[i].len, map[i].type, hook_data))
+        break;
+    }
+
+  return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/i386/xen/startup_pvh.S 
b/grub-core/kern/i386/xen/startup_pvh.S
new file mode 100644
index 000000000..7a9598486
--- /dev/null
+++ b/grub-core/kern/i386/xen/startup_pvh.S
@@ -0,0 +1,80 @@
+/* startup.S - bootstrap GRUB itself */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/machine/memory.h>
+
+        .file   "startup_pvh.S"
+        .text
+        .globl  start, _start
+        .code32
+
+start:
+_start:
+       cld
+       lgdt    gdtdesc
+       ljmp    $GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $1f
+1:
+       movl    $GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %eax
+       mov     %eax, %ds
+       mov     %eax, %es
+       mov     %eax, %ss
+       leal    LOCAL(stack_end), %esp
+
+       /* Save address of start info structure. */
+       mov     %ebx, pvh_start_info
+
+       call    EXT_C(grub_main)
+       /* Doesn't return.  */
+
+       .p2align        3
+gdt:
+       .word   0, 0
+       .byte   0, 0, 0, 0
+
+       /* -- code segment --
+        * base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
+        * type = 32bit code execute/read, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x9A, 0xCF, 0
+
+       /* -- data segment --
+        * base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
+        * type = 32 bit data read/write, DPL = 0
+        */
+       .word   0xFFFF, 0
+       .byte   0, 0x92, 0xCF, 0
+
+       .p2align        3
+/* this is the GDT descriptor */
+gdtdesc:
+       .word   0x17            /* limit */
+       .long   gdt             /* addr */
+
+       .p2align        2
+/* Saved pointer to start info structure. */
+       .globl  pvh_start_info
+pvh_start_info:
+       .long   0
+
+       .bss
+       .space (1 << 22)
+LOCAL(stack_end):      
diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c
index 29f5bc23d..be71eee90 100644
--- a/grub-core/kern/xen/init.c
+++ b/grub-core/kern/xen/init.c
@@ -41,9 +41,13 @@ grub_size_t grub_xen_n_allocated_shared_pages;
 static grub_xen_mfn_t
 grub_xen_ptr2mfn (void *ptr)
 {
+#ifdef GRUB_MACHINE_XEN
   grub_xen_mfn_t *mfn_list =
     (grub_xen_mfn_t *) grub_xen_start_page_addr->mfn_list;
   return mfn_list[(grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE];
+#else
+  return (grub_addr_t) ptr >> GRUB_XEN_LOG_PAGE_SIZE;
+#endif
 }
 
 void *
@@ -104,18 +108,6 @@ grub_machine_get_bootlocation (char **device __attribute__ 
((unused)),
 {
 }
 
-static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
-  __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
-
-#ifdef __x86_64__
-#define NUMBER_OF_LEVELS 4
-#else
-#define NUMBER_OF_LEVELS 3
-#endif
-
-#define LOG_POINTERS_PER_PAGE 9
-#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
-
 void
 grub_xen_store_send (const void *buf_, grub_size_t len)
 {
@@ -337,6 +329,19 @@ grub_xen_setup_gnttab (void)
   grub_xen_grant_table_op (GNTTABOP_setup_table, &gnttab_setup, 1);
 }
 
+#ifdef GRUB_MACHINE_XEN
+static grub_uint8_t window[GRUB_XEN_PAGE_SIZE]
+  __attribute__ ((aligned (GRUB_XEN_PAGE_SIZE)));
+
+#ifdef __x86_64__
+#define NUMBER_OF_LEVELS 4
+#else
+#define NUMBER_OF_LEVELS 3
+#endif
+
+#define LOG_POINTERS_PER_PAGE 9
+#define POINTERS_PER_PAGE (1 << LOG_POINTERS_PER_PAGE)
+
 #define MAX_N_UNUSABLE_PAGES 4
 
 static int
@@ -529,22 +534,45 @@ map_all_pages (void)
   grub_mm_init_region ((void *) heap_start, heap_end - heap_start);
 }
 
+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+  grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
+  grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
+  if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
+    return GRUB_ERR_NONE;
+
+  hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
+       GRUB_MEMORY_RESERVED, hook_data);
+
+  return GRUB_ERR_NONE;
+}
+#endif
+
 extern char _end[];
 
 void
 grub_machine_init (void)
 {
+#ifdef GRUB_MACHINE_XEN
 #ifdef __i386__
   grub_xen_vm_assist (VMASST_CMD_enable, VMASST_TYPE_pae_extended_cr3);
 #endif
+#endif
 
   grub_modbase = ALIGN_UP ((grub_addr_t) _end
                           + GRUB_KERNEL_MACHINE_MOD_GAP,
                           GRUB_KERNEL_MACHINE_MOD_ALIGN);
 
+#ifdef GRUB_MACHINE_XENPVH
+  grub_xen_setup_pvh ();
+#endif
+
   grub_xen_setup_gnttab ();
 
+#ifdef GRUB_MACHINE_XEN
   map_all_pages ();
+#endif
 
   grub_console_init ();
 
@@ -571,17 +599,3 @@ grub_machine_fini (int flags __attribute__ ((unused)))
   grub_xendisk_fini ();
   grub_boot_fini ();
 }
-
-grub_err_t
-grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
-{
-  grub_uint64_t total_pages = grub_xen_start_page_addr->nr_pages;
-  grub_uint64_t usable_pages = grub_xen_start_page_addr->pt_base >> 12;
-  if (hook (0, page2offset (usable_pages), GRUB_MEMORY_AVAILABLE, hook_data))
-    return GRUB_ERR_NONE;
-
-  hook (page2offset (usable_pages), page2offset (total_pages - usable_pages),
-       GRUB_MEMORY_RESERVED, hook_data);
-
-  return GRUB_ERR_NONE;
-}
diff --git a/include/grub/i386/pc/int.h b/include/grub/i386/pc/int.h
index 16a53e4fe..46fb1e397 100644
--- a/include/grub/i386/pc/int.h
+++ b/include/grub/i386/pc/int.h
@@ -51,9 +51,12 @@ struct grub_bios_int_registers
 #define  GRUB_CPU_INT_FLAGS_DEFAULT   0
 #endif
 
+#ifndef GRUB_MACHINE_XENPVH
 void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno,
                                        struct grub_bios_int_registers *regs)
      __attribute__ ((regparm(3)));
+#endif
+
 struct grub_i386_idt
 {
   grub_uint16_t limit;
diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h
index a0aa2c573..8fe1dafa4 100644
--- a/include/grub/i386/tsc.h
+++ b/include/grub/i386/tsc.h
@@ -54,7 +54,7 @@ grub_get_tsc (void)
 static __inline int
 grub_cpu_is_tsc_supported (void)
 {
-#ifndef GRUB_MACHINE_XEN
+#if !defined(GRUB_MACHINE_XEN) && !defined(GRUB_MACHINE_XENPVH)
   grub_uint32_t a,b,c,d;
   if (! grub_cpu_is_cpuid_supported ())
     return 0;
diff --git a/include/grub/i386/xen/hypercall.h 
b/include/grub/i386/xen/hypercall.h
index 198ee94af..4e4c12a49 100644
--- a/include/grub/i386/xen/hypercall.h
+++ b/include/grub/i386/xen/hypercall.h
@@ -26,7 +26,10 @@ EXPORT_FUNC (grub_xen_hypercall) (grub_uint32_t callno, 
grub_uint32_t a0,
                                  grub_uint32_t a1, grub_uint32_t a2,
                                  grub_uint32_t a3, grub_uint32_t a4,
                                  grub_uint32_t a5)
-__attribute__ ((regparm (3), cdecl));
+#ifdef GRUB_MACHINE_XEN
+  __attribute__ ((regparm (3), cdecl))
+#endif
+  ;
 
 static inline int
 grub_xen_sched_op (int cmd, void *arg)
diff --git a/include/grub/i386/xenpvh/boot.h b/include/grub/i386/xenpvh/boot.h
new file mode 100644
index 000000000..6cd23aa83
--- /dev/null
+++ b/include/grub/i386/xenpvh/boot.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/boot.h>
diff --git a/include/grub/i386/xenpvh/console.h 
b/include/grub/i386/xenpvh/console.h
new file mode 100644
index 000000000..305a46d8e
--- /dev/null
+++ b/include/grub/i386/xenpvh/console.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/console.h>
diff --git a/include/grub/i386/xenpvh/int.h b/include/grub/i386/xenpvh/int.h
new file mode 100644
index 000000000..6f9d14a81
--- /dev/null
+++ b/include/grub/i386/xenpvh/int.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/int.h>
diff --git a/include/grub/i386/xenpvh/kernel.h 
b/include/grub/i386/xenpvh/kernel.h
new file mode 100644
index 000000000..d0ceffef4
--- /dev/null
+++ b/include/grub/i386/xenpvh/kernel.h
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER      1
+
+#ifndef ASM_FILE
+
+#define GRUB_KERNEL_USE_RSDP_ADDR      1
+
+extern grub_uint64_t EXPORT_VAR(grub_rsdp_addr);
+
+#endif /* ! ASM_FILE */
+
+#endif /* GRUB_KERNEL_MACHINE_HEADER */
diff --git a/include/grub/i386/xenpvh/memory.h 
b/include/grub/i386/xenpvh/memory.h
new file mode 100644
index 000000000..1501772ac
--- /dev/null
+++ b/include/grub/i386/xenpvh/memory.h
@@ -0,0 +1,54 @@
+/* memory.h - describe the memory map */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2007  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GRUB_MEMORY_MACHINE_LB_HEADER
+#define _GRUB_MEMORY_MACHINE_LB_HEADER      1
+
+#include <grub/symbol.h>
+
+#ifndef ASM_FILE
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/memory.h>
+#endif
+
+#include <grub/i386/memory.h>
+#include <grub/i386/memory_raw.h>
+
+#ifndef ASM_FILE
+
+void grub_machine_mmap_init (void);
+
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+                           grub_uint64_t size __attribute__ ((unused)),
+                           int type __attribute__ ((unused)),
+                           int handle __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+static inline grub_err_t
+grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
+{
+  return GRUB_ERR_NONE;
+}
+
+#endif
+
+#endif /* ! _GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/xenpvh/time.h b/include/grub/i386/xenpvh/time.h
new file mode 100644
index 000000000..2298ee8f4
--- /dev/null
+++ b/include/grub/i386/xenpvh/time.h
@@ -0,0 +1 @@
+#include <grub/i386/pc/time.h>
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index ecd88ca72..b0f1e923c 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -79,7 +79,9 @@ struct grub_module_info64
 #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \
   || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) 
\
   || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \
-  || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) || defined 
(GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN)
+  || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \
+  || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \
+  || defined(GRUB_MACHINE_XENPVH)
 /* FIXME: stack is between 2 heap regions. Move it.  */
 #define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1
 #endif
diff --git a/include/grub/offsets.h b/include/grub/offsets.h
index 330e4c707..1a800521c 100644
--- a/include/grub/offsets.h
+++ b/include/grub/offsets.h
@@ -39,6 +39,7 @@
 #define GRUB_BOOT_I386_PC_KERNEL_SEG   0x800
 
 #define GRUB_KERNEL_I386_PC_LINK_ADDR  0x9000
+#define GRUB_KERNEL_I386_XENPVH_LINK_ADDR      0x100000
 
 /* The upper memory area (starting at 640 kiB).  */
 #define GRUB_MEMORY_I386_PC_UPPER              0xa0000
@@ -102,10 +103,12 @@
 
 #define GRUB_KERNEL_X86_64_XEN_MOD_ALIGN       0x8
 #define GRUB_KERNEL_I386_XEN_MOD_ALIGN 0x8
+#define GRUB_KERNEL_I386_XENPVH_MOD_ALIGN      0x8
 
 /* Non-zero value is only needed for PowerMacs.  */
 #define GRUB_KERNEL_X86_64_XEN_MOD_GAP 0x0
 #define GRUB_KERNEL_I386_XEN_MOD_GAP 0x0
+#define GRUB_KERNEL_I386_XENPVH_MOD_GAP 0x0
 #define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
 #define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
diff --git a/include/grub/xen.h b/include/grub/xen.h
index c31cc10c7..86eb29a44 100644
--- a/include/grub/xen.h
+++ b/include/grub/xen.h
@@ -43,6 +43,7 @@ typedef grub_uint64_t uint64_t;
 
 #include <xen/sched.h>
 #include <xen/grant_table.h>
+#include <xen/hvm/start_info.h>
 #include <xen/io/console.h>
 #include <xen/io/xs_wire.h>
 #include <xen/io/xenbus.h>
@@ -95,6 +96,11 @@ typedef grub_uint64_t grub_xen_mfn_t;
 typedef grub_uint32_t grub_xen_mfn_t;
 #endif
 typedef unsigned int grub_xen_evtchn_t;
+
+#ifdef GRUB_MACHINE_XENPVH
+extern struct hvm_start_info *pvh_start_info;
+void grub_xen_setup_pvh (void);
+#endif
 #endif
 
 #endif
-- 
2.12.3


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.