Commit 9612ebc0 authored by Vladimir Serbinenko's avatar Vladimir Serbinenko

Add new ports: i386-xen and x86_64-xen. This allows running GRUB in

	XEN PV environment and load kernels.
parent 1a46a3a4
2013-11-09 Vladimir Serbinenko <phcoder@gmail.com>
Add new ports: i386-xen and x86_64-xen. This allows running GRUB in
XEN PV environment and load kernels.
2013-11-09 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/loader/i386/multiboot_mbi.c: Handle space in command line.
......@@ -23,6 +23,9 @@ if COND_arm
LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
endif
#FIXME: discover and check XEN headers
CPPFLAGS_XEN = -I/usr/include
# Other options
CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir)/,,$<)\"
......
......@@ -133,6 +133,7 @@ fi
case "$target_cpu"-"$platform" in
x86_64-efi) ;;
x86_64-emu) ;;
x86_64-xen) ;;
x86_64-*) target_cpu=i386 ;;
powerpc64-ieee1275) target_cpu=powerpc ;;
esac
......@@ -141,6 +142,8 @@ esac
case "$target_cpu"-"$platform" in
i386-efi) ;;
x86_64-efi) ;;
i386-xen) ;;
x86_64-xen) ;;
i386-pc) ;;
i386-multiboot) ;;
i386-coreboot) ;;
......@@ -193,6 +196,7 @@ case "$platform" in
coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;;
multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;;
ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
......@@ -1380,6 +1384,8 @@ AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform =
AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen])
AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen])
AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips])
AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc])
......
......@@ -2652,6 +2652,7 @@ Heavily limited platforms:
Lightly limited platforms:
@itemize
@item *-xen: limited only by adress space and RAM size.
@item i386-qemu: kernel.img (.text + .data + .bss) is limited by 392704 bytes.
(core.img would be limited by ROM size but it's unlimited on qemu
@item All EFI platforms: limited by contiguous RAM size and possibly firmware bugs
......@@ -2707,9 +2708,9 @@ by a digit, like @samp{fd0}, or @samp{cd}.
AHCI, PATA (ata), crypto, USB use the name of driver followed by a number.
Memdisk and host are limited to one disk and so it's refered just by driver
name.
RAID (md), ofdisk (ieee1275 and nand), LVM (lvm), LDM and arcdisk (arc) use
intrinsic name of disk prefixed by driver name. Additionally just ``nand''
refers to the disk aliased as ``nand''.
RAID (md), ofdisk (ieee1275 and nand), LVM (lvm), LDM, virtio (vdsk)
and arcdisk (arc) use intrinsic name of disk prefixed by driver name.
Additionally just ``nand'' refers to the disk aliased as ``nand''.
Conflicts are solved by suffixing a number if necessarry.
Commas need to be escaped.
Loopback uses whatever name specified to @command{loopback} command.
......
......@@ -21,6 +21,7 @@
GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_multiboot", "i386_ieee1275", "x86_64_efi",
"i386_xen", "x86_64_xen",
"mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi" ]
......@@ -42,6 +43,7 @@ GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
GROUPS["uboot"] = [ "arm_uboot" ]
GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ]
# emu is a special case so many core functionality isn't needed on this platform
GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
......@@ -49,7 +51,7 @@ GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
# Groups based on hardware features
GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips",
"sparc64_ieee1275", "powerpc_ieee1275"]
GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi")
GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi");
GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"]
GROUPS["usb"] = GROUPS["pci"]
......@@ -59,7 +61,7 @@ GROUPS["videomodules"] = GRUB_PLATFORMS[:];
for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
# Similar for terminfo
GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"] + GROUPS["uboot"];
GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"];
GROUPS["terminfomodule"] = GRUB_PLATFORMS[:];
for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
......
......@@ -130,6 +130,24 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
endif
if COND_i386_xen
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
endif
if COND_x86_64_xen
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
endif
if COND_x86_64_efi
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h
......
......@@ -59,6 +59,11 @@ kernel = {
ia64_efi_ldflags = '-Wl,-r,-d';
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
x86_64_xen_ldflags = '-Wl,-Ttext=0';
x86_64_xen_cppflags = '$(CPPFLAGS_XEN)';
i386_xen_ldflags = '-Wl,-Ttext=0';
i386_xen_cppflags = '$(CPPFLAGS_XEN)';
arm_efi_ldflags = '-Wl,-r,-d';
arm_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version';
......@@ -90,6 +95,8 @@ kernel = {
i386_pc_startup = kern/i386/pc/startup.S;
i386_efi_startup = kern/i386/efi/startup.S;
x86_64_efi_startup = kern/x86_64/efi/startup.S;
i386_xen_startup = kern/i386/xen/startup.S;
x86_64_xen_startup = kern/x86_64/xen/startup.S;
i386_qemu_startup = kern/i386/qemu/startup.S;
i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
i386_coreboot_startup = kern/i386/coreboot/startup.S;
......@@ -146,6 +153,7 @@ kernel = {
terminfoinkernel = lib/arg.c;
i386 = kern/i386/dl.c;
i386_xen = kern/i386/dl.c;
i386_coreboot = kern/i386/coreboot/init.c;
i386_multiboot = kern/i386/coreboot/init.c;
......@@ -164,11 +172,20 @@ kernel = {
i386_efi = kern/i386/efi/init.c;
i386_efi = bus/pci.c;
x86_64_efi = kern/x86_64/dl.c;
x86_64 = kern/x86_64/dl.c;
x86_64_xen = kern/x86_64/dl.c;
x86_64_efi = kern/x86_64/efi/callwrap.S;
x86_64_efi = kern/i386/efi/init.c;
x86_64_efi = bus/pci.c;
xen = kern/i386/tsc.c;
x86_64_xen = kern/x86_64/xen/hypercall.S;
i386_xen = kern/i386/xen/hypercall.S;
xen = kern/xen/init.c;
xen = term/xen/console.c;
xen = disk/xen/xendisk.c;
xen = commands/boot.c;
ia64_efi = kern/ia64/efi/startup.S;
ia64_efi = kern/ia64/efi/init.c;
ia64_efi = kern/ia64/dl.c;
......@@ -578,6 +595,14 @@ module = {
enable = mips_arc;
};
module = {
name = lsxen;
common = commands/xen/lsxen.c;
cppflags = '$(CPPFLAGS_XEN)';
enable = xen;
};
module = {
name = check_nt_hiberfil;
common = commands/i386/nthibr.c;
......@@ -745,8 +770,10 @@ module = {
module = {
name = cpuid;
x86 = commands/i386/cpuid.c;
common = commands/i386/cpuid.c;
enable = x86;
enable = i386_xen;
enable = x86_64_xen;
};
module = {
......@@ -803,6 +830,8 @@ module = {
i386_multiboot = lib/i386/halt.c;
i386_coreboot = lib/i386/halt.c;
i386_qemu = lib/i386/halt.c;
xen = lib/xen/halt.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
efi = lib/efi/halt.c;
ieee1275 = lib/ieee1275/halt.c;
emu = lib/emu/halt.c;
......@@ -821,6 +850,8 @@ module = {
mips_arc = lib/mips/arc/reboot.c;
mips_loongson = lib/mips/loongson/reboot.c;
mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
xen = lib/xen/reboot.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
uboot = lib/uboot/reboot.c;
common = commands/reboot.c;
};
......@@ -1444,6 +1475,11 @@ module = {
common = io/gzio.c;
};
module = {
name = offsetio;
common = io/offset.c;
};
module = {
name = bufio;
common = io/bufio.c;
......@@ -1477,13 +1513,21 @@ module = {
x86 = lib/i386/relocator64.S;
i386 = lib/i386/relocator_asm.S;
x86_64 = lib/x86_64/relocator_asm.S;
i386_xen = lib/i386/relocator_asm.S;
x86_64_xen = lib/x86_64/relocator_asm.S;
x86 = lib/i386/relocator.c;
x86 = lib/i386/relocator_common_c.c;
ieee1275 = lib/ieee1275/relocator.c;
efi = lib/efi/relocator.c;
mips = lib/mips/relocator_asm.S;
mips = lib/mips/relocator.c;
powerpc = lib/powerpc/relocator_asm.S;
powerpc = lib/powerpc/relocator.c;
xen = lib/xen/relocator.c;
i386_xen = lib/i386/xen/relocator.S;
x86_64_xen = lib/x86_64/xen/relocator.S;
xen = lib/i386/relocator_common_c.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
extra_dist = lib/i386/relocator_common.S;
extra_dist = kern/powerpc/cache_flush.S;
......@@ -1491,6 +1535,7 @@ module = {
enable = mips;
enable = powerpc;
enable = x86;
enable = xen;
};
module = {
......@@ -1502,6 +1547,8 @@ module = {
powerpc_ieee1275 = lib/ieee1275/datetime.c;
sparc64_ieee1275 = lib/ieee1275/cmos.c;
powerpc_ieee1275 = lib/ieee1275/cmos.c;
xen = lib/xen/datetime.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
mips_arc = lib/arc/datetime.c;
enable = noemu;
......@@ -1594,6 +1641,12 @@ module = {
module = {
name = linux;
x86 = loader/i386/linux.c;
xen = loader/i386/xen.c;
xen = loader/i386/xen_file.c;
xen = loader/i386/xen_file32.c;
xen = loader/i386/xen_file64.c;
extra_dist = loader/i386/xen_fileXX.c;
xen_cppflags = '$(CPPFLAGS_XEN)';
i386_pc = lib/i386/pc/vesa_modes_table.c;
mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
......@@ -2015,11 +2068,13 @@ module = {
emu = lib/i386/pc/vesa_modes_table.c;
i386_efi = lib/i386/pc/vesa_modes_table.c;
x86_64_efi = lib/i386/pc/vesa_modes_table.c;
xen = lib/i386/pc/vesa_modes_table.c;
enable = i386_pc;
enable = i386_efi;
enable = x86_64_efi;
enable = emu;
enable = xen;
};
module = {
......@@ -2053,8 +2108,12 @@ module = {
module = {
name = backtrace;
x86 = lib/i386/backtrace.c;
i386_xen = lib/i386/backtrace.c;
x86_64_xen = lib/i386/backtrace.c;
common = lib/backtrace.c;
enable = x86;
enable = i386_xen;
enable = x86_64_xen;
};
module = {
......
......@@ -146,8 +146,7 @@ grub_loader_boot (void)
return grub_error (GRUB_ERR_NO_KERNEL,
N_("you need to load the kernel first"));
if (grub_loader_flags & GRUB_LOADER_FLAG_NORETURN)
grub_machine_fini ();
grub_machine_fini (grub_loader_flags);
for (cur = preboots_head; cur; cur = cur->next)
{
......
......@@ -75,6 +75,7 @@ get_uuid (const char *name, char **uuid, int getnative)
/* Native disks. */
case GRUB_DISK_DEVICE_ATA_ID:
case GRUB_DISK_DEVICE_SCSI_ID:
case GRUB_DISK_DEVICE_XEN:
if (getnative)
break;
......
/*
* 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/dl.h>
#include <grub/misc.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/xen.h>
#include <grub/term.h>
GRUB_MOD_LICENSE ("GPLv3+");
static int
hook (const char *dir, void *hook_data __attribute__ ((unused)))
{
grub_printf ("%s\n", dir);
return 0;
}
static grub_err_t
grub_cmd_lsxen (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
char *dir;
grub_err_t err;
char *buf;
if (argc >= 1)
return grub_xenstore_dir (args[0], hook, NULL);
buf = grub_xenstore_get_file ("domid", NULL);
if (!buf)
return grub_errno;
dir = grub_xasprintf ("/local/domain/%s", buf);
grub_free (buf);
err = grub_xenstore_dir (dir, hook, NULL);
grub_free (dir);
return err;
}
static grub_err_t
grub_cmd_catxen (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
const char *dir = "domid";
char *buf;
if (argc >= 1)
dir = args[0];
buf = grub_xenstore_get_file (dir, NULL);
if (!buf)
return grub_errno;
grub_xputs (buf);
grub_xputs ("\n");
grub_free (buf);
return GRUB_ERR_NONE;
}
static grub_command_t cmd_ls, cmd_cat;
GRUB_MOD_INIT (lsxen)
{
cmd_ls = grub_register_command ("xen_ls", grub_cmd_lsxen, "[DIR]",
N_("List XEN storage."));
cmd_cat = grub_register_command ("xen_cat", grub_cmd_catxen, "[DIR]",
N_("List XEN storage."));
}
GRUB_MOD_FINI (lsxen)
{
grub_unregister_command (cmd_ls);
grub_unregister_command (cmd_cat);
}
This diff is collapsed.
......@@ -267,7 +267,8 @@ grub_cbfs_close (grub_file_t file)
return grub_errno;
}
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) \
&& !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
static char *cbfsdisk_addr;
static grub_off_t cbfsdisk_size = 0;
......@@ -375,7 +376,7 @@ static struct grub_fs grub_cbfs_fs = {
GRUB_MOD_INIT (cbfs)
{
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
init_cbfsdisk ();
#endif
grub_fs_register (&grub_cbfs_fs);
......@@ -384,7 +385,7 @@ GRUB_MOD_INIT (cbfs)
GRUB_MOD_FINI (cbfs)
{
grub_fs_unregister (&grub_cbfs_fs);
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
#if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN)
fini_cbfsdisk ();
#endif
}
/*
* 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 <grub/file.h>
#include <grub/dl.h>
GRUB_MOD_LICENSE ("GPLv3+");
struct grub_offset_file
{
grub_file_t parent;
grub_off_t off;
};
static grub_ssize_t
grub_offset_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_offset_file *data = file->data;
if (grub_file_seek (data->parent, data->off + file->offset) == (grub_off_t) -1)
return -1;
return grub_file_read (data->parent, buf, len);
}
static grub_err_t
grub_offset_close (grub_file_t file)
{
struct grub_offset_file *data = file->data;
if (data->parent)
grub_file_close (data->parent);
/* No need to close the same device twice. */
file->device = 0;
return 0;
}
static struct grub_fs grub_offset_fs = {
.name = "offset",
.dir = 0,
.open = 0,
.read = grub_offset_read,
.close = grub_offset_close,
.label = 0,
.next = 0
};
void
grub_file_offset_close (grub_file_t file)
{
struct grub_offset_file *off_data = file->data;
off_data->parent = NULL;
grub_file_close (file);
}
grub_file_t
grub_file_offset_open (grub_file_t parent, grub_off_t start, grub_off_t size)
{
struct grub_offset_file *off_data;
grub_file_t off_file, last_off_file;
grub_file_filter_id_t filter;
off_file = grub_zalloc (sizeof (*off_file));
off_data = grub_zalloc (sizeof (*off_data));
if (!off_file || !off_data)
{
grub_free (off_file);
grub_free (off_data);
return 0;
}
off_data->off = start;
off_data->parent = parent;
off_file->device = parent->device;
off_file->data = off_data;
off_file->fs = &grub_offset_fs;
off_file->size = size;
last_off_file = NULL;
for (filter = GRUB_FILE_FILTER_COMPRESSION_FIRST;
off_file && filter <= GRUB_FILE_FILTER_COMPRESSION_LAST; filter++)
if (grub_file_filters_enabled[filter])
{
last_off_file = off_file;
off_file = grub_file_filters_enabled[filter] (off_file, parent->name);
}
if (!off_file)
{
off_data->parent = NULL;
grub_file_close (last_off_file);
return 0;
}
return off_file;
}
......@@ -41,6 +41,7 @@
#include <grub/env.h>
#include <grub/partition.h>
#include <grub/i18n.h>
#include <grub/loader.h>
#include <grub/util/misc.h>
#include "progname.h"
......@@ -75,9 +76,10 @@ grub_machine_get_bootlocation (char **device, char **path)
}
void
grub_machine_fini (void)
grub_machine_fini (int flags)
{
grub_console_fini ();
if (flags & GRUB_LOADER_FLAG_NORETURN)
grub_console_fini ();
}
......
......@@ -130,8 +130,9 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
}
void
grub_machine_fini (void)
grub_machine_fini (int flags)
{
grub_vga_text_fini ();
if (flags & GRUB_LOADER_FLAG_NORETURN)
grub_vga_text_fini ();
grub_stop_floppy ();
}
......@@ -35,7 +35,8 @@ grub_machine_init (void)
}
void
grub_machine_fini (void)
grub_machine_fini (int flags)
{
grub_efi_fini ();
if (flags & GRUB_LOADER_FLAG_NORETURN)
grub_efi_fini ();
}
......@@ -239,8 +239,9 @@ grub_machine_init (void)
}
void
grub_machine_fini (void)
grub_machine_fini (int flags)
{
grub_console_fini ();
if (flags & GRUB_LOADER_FLAG_NORETURN)
grub_console_fini ();
grub_stop_floppy ();
}
......@@ -277,8 +277,9 @@ grub_machine_get_bootlocation (char **device __attribute__ ((unused)),
}
void
grub_machine_fini (void)
grub_machine_fini (int flags)
{
grub_vga_text_fini ();
if (flags & GRUB_LOADER_FLAG_NORETURN)
grub_vga_text_fini ();
grub_stop_floppy ();
}
......@@ -25,7 +25,11 @@
#include <grub/misc.h>
#include <grub/i386/tsc.h>
#include <grub/i386/cpuid.h>
#ifdef GRUB_MACHINE_XEN
#include <grub/xen.h>
#else
#include <grub/i386/pit.h>
#endif
#include <grub/cpu/io.h>
/* This defines the value TSC had at the epoch (that is, when we calibrated it). */
......@@ -65,6 +69,8 @@ grub_cpu_is_tsc_supported (void)
return (d & (1 << 4)) != 0;
}
#ifndef GRUB_MACHINE_XEN
static void
grub_pit_wait (grub_uint16_t tics)
{
......@@ -92,6 +98,7 @@ grub_pit_wait (grub_uint16_t tics)
& ~ (GRUB_PIT_SPK_DATA | GRUB_PIT_SPK_TMR2),
GRUB_PIT_SPEAKER_PORT);
}
#endif
static grub_uint64_t
grub_tsc_get_time_ms (void)
......@@ -103,6 +110,7 @@ grub_tsc_get_time_ms (void)
return ((al * grub_tsc_rate) >> 32) + ah * grub_tsc_rate;
}
#ifndef GRUB_MACHINE_XEN
/* Calibrate the TSC based on the RTC. */
static void
calibrate_tsc (void)
......@@ -116,10 +124,22 @@ calibrate_tsc (void)
grub_tsc_rate = grub_divmod64 ((55ULL << 32), end_tsc - tsc_boot_time, 0);
}
#endif
void
grub_tsc_init (void)
{
#ifdef GRUB_MACHINE_XEN
grub_uint64_t t;
tsc_boot_time = grub_get_tsc ();
t = grub_xen_shared_info->vcpu_info[0].time.tsc_to_system_mul;
if (grub_xen_shared_info->vcpu_info[0].time.tsc_shift > 0)
t <<= grub_xen_shared_info->vcpu_info[0].time.tsc_shift;
else
t >>= -grub_xen_shared_info->vcpu_info[0].time.tsc_shift;
grub_tsc_rate = grub_divmod64 (t, 1000000, 0);
grub_install_get_time_ms (grub_tsc_get_time_ms);
#else
if (grub_cpu_is_tsc_supported ())
{
calibrate_tsc ();
......@@ -133,4 +153,5 @@ grub_tsc_init (void)
grub_fatal ("no TSC found");
#endif
}
#endif
}
/* hypercall.S - wrappers for Xen hypercalls */
/*
* 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 <grub/symbol.h>
#include <grub/xen.h>
FUNCTION(grub_xen_hypercall)
pushl %ebp
movl %esp, %ebp
pushl %esi
pushl %edi
pushl %ebx
/* call number already in %eax. */
/* %edx -> %ebx*/
/* %ecx -> %ecx*/
movl %edx, %ebx
movl 8(%ebp), %edx
movl 12(%ebp), %esi
movl 16(%ebp), %edi
movl 20(%ebp), %ebp
int $0x82