commit-hurd
[Top][All Lists]
Advanced

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

[gnumach] 01/02: Add powerdown support and fix Xen safety


From: Samuel Thibault
Subject: [gnumach] 01/02: Add powerdown support and fix Xen safety
Date: Fri, 25 Jul 2014 23:30:07 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository gnumach.

commit fcc6185837e1b2e915dc672731a2d8f4fb830476
Author: Samuel Thibault <address@hidden>
Date:   Fri Jul 25 17:32:31 2014 +0000

    Add powerdown support and fix Xen safety
    
      * patches/git-halt.patch: Add ACPI powerdown support.
      * patches/git-xen-memory-clobber.patch: Add missing memory clobbers.
---
 debian/changelog                            |    7 +
 debian/patches/git-halt.patch               | 2500 +++++++++++++++++++++++++++
 debian/patches/git-xen-memory-clobber.patch |   21 +
 debian/patches/series                       |    2 +
 4 files changed, 2530 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 581b0d4..790fdc9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+gnumach (2:1.4-11) unstable; urgency=medium
+
+  * patches/git-halt.patch: Add ACPI powerdown support.
+  * patches/git-xen-memory-clobber.patch: Add missing memory clobbers.
+
+ -- Samuel Thibault <address@hidden>  Fri, 25 Jul 2014 17:05:41 +0000
+
 gnumach (2:1.4-10) unstable; urgency=medium
 
   * patches/git-notify_translatable{,2}.patch: New patch to make notify
diff --git a/debian/patches/git-halt.patch b/debian/patches/git-halt.patch
new file mode 100644
index 0000000..f0f1d2f
--- /dev/null
+++ b/debian/patches/git-halt.patch
@@ -0,0 +1,2500 @@
+commit 3bb2b68bc84b9cb11aae7b46eeec3c5eb3363f54
+Author: Justus Winter <address@hidden>
+Date:   Fri May 2 21:33:01 2014 +0200
+
+    i386: add io_map_cached
+    
+    io_map_cached is like io_map, but reuses the old mapping if it is
+    applicable.
+    
+    * i386/i386/io_map.c: Add io_map_cached.
+
+diff --git a/i386/i386/io_map.c b/i386/i386/io_map.c
+index 74e0b47..03d7152 100644
+--- a/i386/i386/io_map.c
++++ b/i386/i386/io_map.c
+@@ -58,3 +58,32 @@ io_map(
+                       VM_PROT_READ|VM_PROT_WRITE);
+       return (start);
+ }
++
++/*
++ * Allocate and map memory for devices that may need to be mapped before
++ * Mach VM is running.
++ *
++ * This maps the all pages containing [PHYS_ADDR:PHYS_ADDR + SIZE].
++ * For contiguous requests to those pages will reuse the previously
++ * established mapping.
++ */
++vm_offset_t
++io_map_cached(
++      vm_offset_t     phys_addr,
++      vm_size_t       size)
++{
++  static vm_offset_t base;
++  static vm_size_t length;
++  static vm_offset_t map;
++
++  if (! map
++      || (phys_addr < base)
++      || (base + length < phys_addr + size))
++    {
++      base = trunc_page(phys_addr);
++      length = round_page(phys_addr - base + size);
++      map = io_map(base, length);
++    }
++
++  return map + (phys_addr - base);
++}
+commit c031b41b783cc99c0bd5aac7d14c1d6e34520397
+Author: Justus Winter <address@hidden>
+Date:   Sat May 3 01:33:14 2014 +0200
+
+    i386: use ACPI to power off the machine
+    
+    This is a mostly verbatim copy of acpihalt.c from GRUB2 with a little
+    bit of glue code.
+    
+    * i386/Makefrag.am (libkernel_a_SOURCES): Add the new files.
+    * i386/grub/acpi.h: Verbatim copy from GRUB2.
+    * i386/grub/compiler.h: Likewise.
+    * i386/grub/cpu/io.h: Likewise.
+    * i386/grub/cpu/time.h: Likewise.
+    * i386/grub/cpu/types.h: Likewise.
+    * i386/grub/err.h: Likewise.
+    * i386/grub/misc.h: Likewise.
+    * i386/grub/mm.h: Likewise.
+    * i386/grub/symbol.h: Likewise.
+    * i386/grub/time.h: Likewise.
+    * i386/grub/types.h: Likewise.
+    * i386/i386at/acpi.c: Likewise.
+    * i386/i386at/acpihalt.c: Likewise.
+    (grub_acpi_halt): Map physical addresses.
+    * i386/i386at/acpihalt.h: New file.
+    * i386/grub/glue.h: Some glue macros.
+    * i386/grub/i18n.h: Stub out i18n.
+    * i386/i386at/grub_glue.c: Some glue code.
+    * i386/i386at/model_dep.c (halt_all_cpus): Use grub_acpi_halt.
+
+diff --git a/i386/Makefrag.am b/i386/Makefrag.am
+index cac2267..4dd6a9f 100644
+--- a/i386/Makefrag.am
++++ b/i386/Makefrag.am
+@@ -55,6 +55,25 @@ libkernel_a_SOURCES += \
+       i386/i386at/pic_isa.c \
+       i386/i386at/rtc.c \
+       i386/i386at/rtc.h
++
++libkernel_a_SOURCES += \
++      i386/i386at/acpihalt.c \
++      i386/i386at/acpihalt.h \
++      i386/i386at/acpi.c \
++      i386/i386at/grub_glue.c \
++      i386/grub/err.h \
++      i386/grub/cpu/io.h \
++      i386/grub/cpu/types.h \
++      i386/grub/cpu/time.h \
++      i386/grub/mm.h \
++      i386/grub/acpi.h \
++      i386/grub/symbol.h \
++      i386/grub/misc.h \
++      i386/grub/types.h \
++      i386/grub/time.h \
++      i386/grub/i18n.h \
++      i386/grub/compiler.h \
++      i386/grub/glue.h
+ endif
+ 
+ #
+diff --git a/i386/grub/acpi.h b/i386/grub/acpi.h
+new file mode 100644
+index 0000000..2ac2bd6
+--- /dev/null
++++ b/i386/grub/acpi.h
+@@ -0,0 +1,220 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 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_ACPI_HEADER
++#define GRUB_ACPI_HEADER      1
++
++#ifndef GRUB_DSDT_TEST
++#include <grub/types.h>
++#include <grub/err.h>
++#endif
++
++#define GRUB_RSDP_SIGNATURE "RSD PTR "
++#define GRUB_RSDP_SIGNATURE_SIZE 8
++
++struct grub_acpi_rsdp_v10
++{
++  grub_uint8_t signature[GRUB_RSDP_SIGNATURE_SIZE];
++  grub_uint8_t checksum;
++  grub_uint8_t oemid[6];
++  grub_uint8_t revision;
++  grub_uint32_t rsdt_addr;
++} GRUB_PACKED;
++
++struct grub_acpi_rsdp_v20
++{
++  struct grub_acpi_rsdp_v10 rsdpv1;
++  grub_uint32_t length;
++  grub_uint64_t xsdt_addr;
++  grub_uint8_t checksum;
++  grub_uint8_t reserved[3];
++} GRUB_PACKED;
++
++struct grub_acpi_table_header
++{
++  grub_uint8_t signature[4];
++  grub_uint32_t length;
++  grub_uint8_t revision;
++  grub_uint8_t checksum;
++  grub_uint8_t oemid[6];
++  grub_uint8_t oemtable[8];
++  grub_uint32_t oemrev;
++  grub_uint8_t creator_id[4];
++  grub_uint32_t creator_rev;
++} GRUB_PACKED;
++
++#define GRUB_ACPI_FADT_SIGNATURE "FACP"
++
++struct grub_acpi_fadt
++{
++  struct grub_acpi_table_header hdr;
++  grub_uint32_t facs_addr;
++  grub_uint32_t dsdt_addr;
++  grub_uint8_t somefields1[20];
++  grub_uint32_t pm1a;
++  grub_uint8_t somefields2[64];
++  grub_uint64_t facs_xaddr;
++  grub_uint64_t dsdt_xaddr;
++  grub_uint8_t somefields3[96];
++} GRUB_PACKED;
++
++#define GRUB_ACPI_MADT_SIGNATURE "APIC"
++
++struct grub_acpi_madt_entry_header
++{
++  grub_uint8_t type;
++  grub_uint8_t len;
++};
++
++struct grub_acpi_madt
++{
++  struct grub_acpi_table_header hdr;
++  grub_uint32_t lapic_addr;
++  grub_uint32_t flags;
++  struct grub_acpi_madt_entry_header entries[0];
++};
++
++enum
++  {
++    GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC = 0,
++    GRUB_ACPI_MADT_ENTRY_TYPE_IOAPIC = 1,
++    GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE = 2,
++    GRUB_ACPI_MADT_ENTRY_TYPE_LAPIC_NMI = 4,
++    GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC = 6,
++    GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC = 7,
++    GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE = 8
++  };
++
++struct grub_acpi_madt_entry_lapic
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t acpiid;
++  grub_uint8_t apicid;
++  grub_uint32_t flags;
++};
++
++struct grub_acpi_madt_entry_ioapic
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t id;
++  grub_uint8_t pad;
++  grub_uint32_t address;
++  grub_uint32_t global_sys_interrupt;
++};
++
++struct grub_acpi_madt_entry_interrupt_override
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t bus;
++  grub_uint8_t source;
++  grub_uint32_t global_sys_interrupt;
++  grub_uint16_t flags;
++} GRUB_PACKED;
++
++
++struct grub_acpi_madt_entry_lapic_nmi
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t acpiid;
++  grub_uint16_t flags;
++  grub_uint8_t lint;
++} GRUB_PACKED;
++
++struct grub_acpi_madt_entry_sapic
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t id;
++  grub_uint8_t pad;
++  grub_uint32_t global_sys_interrupt_base;
++  grub_uint64_t addr;
++};
++
++struct grub_acpi_madt_entry_lsapic
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint8_t cpu_id;
++  grub_uint8_t id;
++  grub_uint8_t eid;
++  grub_uint8_t pad[3];
++  grub_uint32_t flags;
++  grub_uint32_t cpu_uid;
++  grub_uint8_t cpu_uid_str[0];
++};
++
++struct grub_acpi_madt_entry_platform_int_source
++{
++  struct grub_acpi_madt_entry_header hdr;
++  grub_uint16_t flags;
++  grub_uint8_t inttype;
++  grub_uint8_t cpu_id;
++  grub_uint8_t cpu_eid;
++  grub_uint8_t sapic_vector;
++  grub_uint32_t global_sys_int;
++  grub_uint32_t src_flags;
++};
++
++enum
++  {
++    GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED = 1
++  };
++
++#ifndef GRUB_DSDT_TEST
++struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
++struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
++struct grub_acpi_rsdp_v10 *grub_machine_acpi_get_rsdpv1 (void);
++struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void);
++grub_uint8_t grub_byte_checksum (void *base, grub_size_t size);
++
++grub_err_t grub_acpi_create_ebda (void);
++
++void grub_acpi_halt (void);
++#endif
++
++#define GRUB_ACPI_SLP_EN (1 << 13)
++#define GRUB_ACPI_SLP_TYP_OFFSET 10
++
++enum
++  {
++    GRUB_ACPI_OPCODE_ZERO = 0, GRUB_ACPI_OPCODE_ONE = 1,
++    GRUB_ACPI_OPCODE_NAME = 8, GRUB_ACPI_OPCODE_BYTE_CONST = 0x0a,
++    GRUB_ACPI_OPCODE_WORD_CONST = 0x0b,
++    GRUB_ACPI_OPCODE_DWORD_CONST = 0x0c,
++    GRUB_ACPI_OPCODE_STRING_CONST = 0x0d,
++    GRUB_ACPI_OPCODE_SCOPE = 0x10,
++    GRUB_ACPI_OPCODE_BUFFER = 0x11,
++    GRUB_ACPI_OPCODE_PACKAGE = 0x12,
++    GRUB_ACPI_OPCODE_METHOD = 0x14, GRUB_ACPI_OPCODE_EXTOP = 0x5b,
++    GRUB_ACPI_OPCODE_CREATE_WORD_FIELD = 0x8b,
++    GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD = 0x8c,
++    GRUB_ACPI_OPCODE_IF = 0xa0, GRUB_ACPI_OPCODE_ONES = 0xff
++  };
++enum
++  {
++    GRUB_ACPI_EXTOPCODE_MUTEX = 0x01,
++    GRUB_ACPI_EXTOPCODE_EVENT_OP = 0x02,
++    GRUB_ACPI_EXTOPCODE_OPERATION_REGION = 0x80,
++    GRUB_ACPI_EXTOPCODE_FIELD_OP = 0x81,
++    GRUB_ACPI_EXTOPCODE_DEVICE_OP = 0x82,
++    GRUB_ACPI_EXTOPCODE_PROCESSOR_OP = 0x83,
++    GRUB_ACPI_EXTOPCODE_POWER_RES_OP = 0x84,
++    GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP = 0x85,
++    GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP = 0x86,
++    GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP = 0x87,
++  };
++
++#endif /* ! GRUB_ACPI_HEADER */
+diff --git a/i386/grub/compiler.h b/i386/grub/compiler.h
+new file mode 100644
+index 0000000..c9e1d7a
+--- /dev/null
++++ b/i386/grub/compiler.h
+@@ -0,0 +1,51 @@
++/* compiler.h - macros for various compiler features */
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2014  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_COMPILER_HEADER
++#define GRUB_COMPILER_HEADER  1
++
++/* GCC version checking borrowed from glibc. */
++#if defined(__GNUC__) && defined(__GNUC_MINOR__)
++#  define GNUC_PREREQ(maj,min) \
++      ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
++#else
++#  define GNUC_PREREQ(maj,min) 0
++#endif
++
++/* Does this compiler support compile-time error attributes? */
++#if GNUC_PREREQ(4,3)
++#  define ATTRIBUTE_ERROR(msg) \
++      __attribute__ ((__error__ (msg)))
++#else
++#  define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn))
++#endif
++
++#if GNUC_PREREQ(4,4)
++#  define GNU_PRINTF gnu_printf
++#else
++#  define GNU_PRINTF printf
++#endif
++
++#if GNUC_PREREQ(3,4)
++#  define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
++#else
++#  define WARN_UNUSED_RESULT
++#endif
++
++#endif /* ! GRUB_COMPILER_HEADER */
+diff --git a/i386/grub/cpu/io.h b/i386/grub/cpu/io.h
+new file mode 100644
+index 0000000..ae12a3e
+--- /dev/null
++++ b/i386/grub/cpu/io.h
+@@ -0,0 +1,72 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 1996,2000,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/>.
++ */
++
++/* Based on sys/io.h from GNU libc. */
++
++#ifndef       GRUB_IO_H
++#define       GRUB_IO_H       1
++
++typedef unsigned short int grub_port_t;
++
++static __inline unsigned char
++grub_inb (unsigned short int port)
++{
++  unsigned char _v;
++
++  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
++  return _v;
++}
++
++static __inline unsigned short int
++grub_inw (unsigned short int port)
++{
++  unsigned short _v;
++
++  __asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (port));
++  return _v;
++}
++
++static __inline unsigned int
++grub_inl (unsigned short int port)
++{
++  unsigned int _v;
++
++  __asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (port));
++  return _v;
++}
++
++static __inline void
++grub_outb (unsigned char value, unsigned short int port)
++{
++  __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
++}
++
++static __inline void
++grub_outw (unsigned short int value, unsigned short int port)
++{
++  __asm__ __volatile__ ("outw %w0,%w1": :"a" (value), "Nd" (port));
++
++}
++
++static __inline void
++grub_outl (unsigned int value, unsigned short int port)
++{
++  __asm__ __volatile__ ("outl %0,%w1": :"a" (value), "Nd" (port));
++}
++
++#endif /* _SYS_IO_H */
+diff --git a/i386/grub/cpu/time.h b/i386/grub/cpu/time.h
+new file mode 100644
+index 0000000..842882c
+--- /dev/null
++++ b/i386/grub/cpu/time.h
+@@ -0,0 +1,29 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 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 KERNEL_CPU_TIME_HEADER
++#define KERNEL_CPU_TIME_HEADER        1
++
++static __inline void
++grub_cpu_idle (void)
++{
++  /* FIXME: this can't work until we handle interrupts.  */
++/*  __asm__ __volatile__ ("hlt"); */
++}
++
++#endif /* ! KERNEL_CPU_TIME_HEADER */
+diff --git a/i386/grub/cpu/types.h b/i386/grub/cpu/types.h
+new file mode 100644
+index 0000000..c20063f
+--- /dev/null
++++ b/i386/grub/cpu/types.h
+@@ -0,0 +1,33 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002,2006,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_TYPES_CPU_HEADER
++#define GRUB_TYPES_CPU_HEADER 1
++
++/* The size of void *.  */
++#define GRUB_TARGET_SIZEOF_VOID_P     4
++
++/* The size of long.  */
++#define GRUB_TARGET_SIZEOF_LONG               4
++
++/* i386 is little-endian.  */
++#undef GRUB_TARGET_WORDS_BIGENDIAN
++
++#define GRUB_HAVE_UNALIGNED_ACCESS 1
++
++#endif /* ! GRUB_TYPES_CPU_HEADER */
+diff --git a/i386/grub/err.h b/i386/grub/err.h
+new file mode 100644
+index 0000000..1590c68
+--- /dev/null
++++ b/i386/grub/err.h
+@@ -0,0 +1,96 @@
++/* err.h - error numbers and prototypes */
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002,2005,2007,2008 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_ERR_HEADER
++#define GRUB_ERR_HEADER       1
++
++#include <grub/symbol.h>
++
++#define GRUB_MAX_ERRMSG               256
++
++typedef enum
++  {
++    GRUB_ERR_NONE = 0,
++    GRUB_ERR_TEST_FAILURE,
++    GRUB_ERR_BAD_MODULE,
++    GRUB_ERR_OUT_OF_MEMORY,
++    GRUB_ERR_BAD_FILE_TYPE,
++    GRUB_ERR_FILE_NOT_FOUND,
++    GRUB_ERR_FILE_READ_ERROR,
++    GRUB_ERR_BAD_FILENAME,
++    GRUB_ERR_UNKNOWN_FS,
++    GRUB_ERR_BAD_FS,
++    GRUB_ERR_BAD_NUMBER,
++    GRUB_ERR_OUT_OF_RANGE,
++    GRUB_ERR_UNKNOWN_DEVICE,
++    GRUB_ERR_BAD_DEVICE,
++    GRUB_ERR_READ_ERROR,
++    GRUB_ERR_WRITE_ERROR,
++    GRUB_ERR_UNKNOWN_COMMAND,
++    GRUB_ERR_INVALID_COMMAND,
++    GRUB_ERR_BAD_ARGUMENT,
++    GRUB_ERR_BAD_PART_TABLE,
++    GRUB_ERR_UNKNOWN_OS,
++    GRUB_ERR_BAD_OS,
++    GRUB_ERR_NO_KERNEL,
++    GRUB_ERR_BAD_FONT,
++    GRUB_ERR_NOT_IMPLEMENTED_YET,
++    GRUB_ERR_SYMLINK_LOOP,
++    GRUB_ERR_BAD_COMPRESSED_DATA,
++    GRUB_ERR_MENU,
++    GRUB_ERR_TIMEOUT,
++    GRUB_ERR_IO,
++    GRUB_ERR_ACCESS_DENIED,
++    GRUB_ERR_EXTRACTOR,
++    GRUB_ERR_NET_BAD_ADDRESS,
++    GRUB_ERR_NET_ROUTE_LOOP,
++    GRUB_ERR_NET_NO_ROUTE,
++    GRUB_ERR_NET_NO_ANSWER,
++    GRUB_ERR_NET_NO_CARD,
++    GRUB_ERR_WAIT,
++    GRUB_ERR_BUG,
++    GRUB_ERR_NET_PORT_CLOSED,
++    GRUB_ERR_NET_INVALID_RESPONSE,
++    GRUB_ERR_NET_UNKNOWN_ERROR,
++    GRUB_ERR_NET_PACKET_TOO_BIG,
++    GRUB_ERR_NET_NO_DOMAIN,
++    GRUB_ERR_EOF,
++    GRUB_ERR_BAD_SIGNATURE
++  }
++grub_err_t;
++
++struct grub_error_saved
++{
++  grub_err_t grub_errno;
++  char errmsg[GRUB_MAX_ERRMSG];
++};
++
++extern grub_err_t EXPORT_VAR(grub_errno);
++extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
++
++grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
++void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ 
((noreturn));
++void EXPORT_FUNC(grub_error_push) (void);
++int EXPORT_FUNC(grub_error_pop) (void);
++void EXPORT_FUNC(grub_print_error) (void);
++extern int EXPORT_VAR(grub_err_printed_errors);
++int grub_err_printf (const char *fmt, ...)
++     __attribute__ ((format (__printf__, 1, 2)));
++
++#endif /* ! GRUB_ERR_HEADER */
+diff --git a/i386/grub/glue.h b/i386/grub/glue.h
+new file mode 100644
+index 0000000..e1c62eb
+--- /dev/null
++++ b/i386/grub/glue.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2014 Free Software Foundation.
++ *
++ * 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 _GRUB_GLUE_H
++#define _GRUB_GLUE_H
++
++#define GRUB_FILE __FILE__
++#define grub_memcmp memcmp
++#define grub_printf printf
++#define grub_puts_ puts
++
++#include <mach/mach_types.h>
++#include <i386/vm_param.h>
++
++vm_offset_t io_map_cached(vm_offset_t phys_addr, vm_size_t size);
++
++#endif /* _GRUB_GLUE_H */
+diff --git a/i386/grub/i18n.h b/i386/grub/i18n.h
+new file mode 100644
+index 0000000..8b53357
+--- /dev/null
++++ b/i386/grub/i18n.h
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (c) 2014 Free Software Foundation.
++ *
++ * 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 _GRUB_I18N_H
++#define _GRUB_I18N_H
++
++/* No i18n please.  */
++#define _(x) x
++#define N_(x) x
++
++#endif /* _GRUB_I18N_H */
+diff --git a/i386/grub/misc.h b/i386/grub/misc.h
+new file mode 100644
+index 0000000..c6cd456
+--- /dev/null
++++ b/i386/grub/misc.h
+@@ -0,0 +1,517 @@
++/* misc.h - prototypes for misc functions */
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010  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_MISC_HEADER
++#define GRUB_MISC_HEADER      1
++
++#include <stdarg.h>
++#include <grub/types.h>
++#include <grub/symbol.h>
++#include <grub/err.h>
++#include <grub/i18n.h>
++#include <grub/compiler.h>
++
++#define ALIGN_UP(addr, align) \
++      ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1))
++#define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) 
- 1))
++#define ALIGN_DOWN(addr, align) \
++      ((addr) & ~((typeof (addr)) align - 1))
++#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
++#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; }
++
++#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, 
condition, __VA_ARGS__)
++
++void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n);
++char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src);
++
++static inline char *
++grub_strncpy (char *dest, const char *src, int c)
++{
++  char *p = dest;
++
++  while ((*p++ = *src++) != '\0' && --c)
++    ;
++
++  return dest;
++}
++
++static inline char *
++grub_stpcpy (char *dest, const char *src)
++{
++  char *d = dest;
++  const char *s = src;
++
++  do
++    *d++ = *s;
++  while (*s++ != '\0');
++
++  return d - 1;
++}
++
++/* XXX: If grub_memmove is too slow, we must implement grub_memcpy.  */
++static inline void *
++grub_memcpy (void *dest, const void *src, grub_size_t n)
++{
++  return grub_memmove (dest, src, n);
++}
++
++#if defined (__APPLE__) && defined(__i386__) && !defined (GRUB_UTIL)
++#define GRUB_BUILTIN_ATTR  __attribute__ ((regparm(0)))
++#else
++#define GRUB_BUILTIN_ATTR
++#endif
++
++#if defined(__x86_64__) && !defined (GRUB_UTIL)
++#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__)
++#define GRUB_ASM_ATTR __attribute__ ((sysv_abi))
++#else
++#define GRUB_ASM_ATTR
++#endif
++#endif
++
++/* Prototypes for aliases.  */
++#ifndef GRUB_UTIL
++int GRUB_BUILTIN_ATTR EXPORT_FUNC(memcmp) (const void *s1, const void *s2, 
grub_size_t n);
++void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memmove) (void *dest, const void *src, 
grub_size_t n);
++void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memcpy) (void *dest, const void *src, 
grub_size_t n);
++void *GRUB_BUILTIN_ATTR EXPORT_FUNC(memset) (void *s, int c, grub_size_t n);
++
++#ifdef __APPLE__
++void GRUB_BUILTIN_ATTR EXPORT_FUNC (__bzero) (void *s, grub_size_t n);
++#endif
++
++#endif
++
++int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n);
++int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2);
++int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n);
++
++char *EXPORT_FUNC(grub_strchr) (const char *s, int c);
++char *EXPORT_FUNC(grub_strrchr) (const char *s, int c);
++int EXPORT_FUNC(grub_strword) (const char *s, const char *w);
++
++/* Copied from gnulib.
++   Written by Bruno Haible <address@hidden>, 2005. */
++static inline char *
++grub_strstr (const char *haystack, const char *needle)
++{
++  /* Be careful not to look at the entire extent of haystack or needle
++     until needed.  This is useful because of these two cases:
++       - haystack may be very long, and a match of needle found early,
++       - needle may be very long, and not even a short initial segment of
++       needle may be found in haystack.  */
++  if (*needle != '\0')
++    {
++      /* Speed up the following searches of needle by caching its first
++       character.  */
++      char b = *needle++;
++
++      for (;; haystack++)
++      {
++        if (*haystack == '\0')
++          /* No match.  */
++          return 0;
++        if (*haystack == b)
++          /* The first character matches.  */
++          {
++            const char *rhaystack = haystack + 1;
++            const char *rneedle = needle;
++
++            for (;; rhaystack++, rneedle++)
++              {
++                if (*rneedle == '\0')
++                  /* Found a match.  */
++                  return (char *) haystack;
++                if (*rhaystack == '\0')
++                  /* No match.  */
++                  return 0;
++                if (*rhaystack != *rneedle)
++                  /* Nothing in this round.  */
++                  break;
++              }
++          }
++      }
++    }
++  else
++    return (char *) haystack;
++}
++
++int EXPORT_FUNC(grub_isspace) (int c);
++
++static inline int
++grub_isprint (int c)
++{
++  return (c >= ' ' && c <= '~');
++}
++
++static inline int
++grub_iscntrl (int c)
++{
++  return (c >= 0x00 && c <= 0x1F) || c == 0x7F;
++}
++
++static inline int
++grub_isalpha (int c)
++{
++  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
++}
++
++static inline int
++grub_islower (int c)
++{
++  return (c >= 'a' && c <= 'z');
++}
++
++static inline int
++grub_isupper (int c)
++{
++  return (c >= 'A' && c <= 'Z');
++}
++
++static inline int
++grub_isgraph (int c)
++{
++  return (c >= '!' && c <= '~');
++}
++
++static inline int
++grub_isdigit (int c)
++{
++  return (c >= '0' && c <= '9');
++}
++
++static inline int
++grub_isxdigit (int c)
++{
++  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c 
<= 'F');
++}
++
++static inline int
++grub_isalnum (int c)
++{
++  return grub_isalpha (c) || grub_isdigit (c);
++}
++
++static inline int
++grub_tolower (int c)
++{
++  if (c >= 'A' && c <= 'Z')
++    return c - 'A' + 'a';
++
++  return c;
++}
++
++static inline int
++grub_toupper (int c)
++{
++  if (c >= 'a' && c <= 'z')
++    return c - 'a' + 'A';
++
++  return c;
++}
++
++static inline int
++grub_strcasecmp (const char *s1, const char *s2)
++{
++  while (*s1 && *s2)
++    {
++      if (grub_tolower ((grub_uint8_t) *s1)
++        != grub_tolower ((grub_uint8_t) *s2))
++      break;
++
++      s1++;
++      s2++;
++    }
++
++  return (int) grub_tolower ((grub_uint8_t) *s1)
++    - (int) grub_tolower ((grub_uint8_t) *s2);
++}
++
++static inline int
++grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
++{
++  if (n == 0)
++    return 0;
++
++  while (*s1 && *s2 && --n)
++    {
++      if (grub_tolower (*s1) != grub_tolower (*s2))
++      break;
++
++      s1++;
++      s2++;
++    }
++
++  return (int) grub_tolower ((grub_uint8_t) *s1)
++    - (int) grub_tolower ((grub_uint8_t) *s2);
++}
++
++unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int 
base);
++unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, 
int base);
++
++static inline long
++grub_strtol (const char *str, char **end, int base)
++{
++  int negative = 0;
++  unsigned long long magnitude;
++
++  while (*str && grub_isspace (*str))
++    str++;
++
++  if (*str == '-')
++    {
++      negative = 1;
++      str++;
++    }
++
++  magnitude = grub_strtoull (str, end, base);
++  if (negative)
++    {
++      if (magnitude > (unsigned long) GRUB_LONG_MAX + 1)
++        {
++          grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
++          return GRUB_LONG_MIN;
++        }
++      return -((long) magnitude);
++    }
++  else
++    {
++      if (magnitude > GRUB_LONG_MAX)
++        {
++          grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
++          return GRUB_LONG_MAX;
++        }
++      return (long) magnitude;
++    }
++}
++
++char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT;
++char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) 
WARN_UNUSED_RESULT;
++void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
++grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT;
++int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format 
(GNU_PRINTF, 1, 2)));
++int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format 
(GNU_PRINTF, 1, 2)));
++
++/* Replace all `ch' characters of `input' with `with' and copy the
++   result into `output'; return EOS address of `output'. */
++static inline char *
++grub_strchrsub (char *output, const char *input, char ch, const char *with)
++{
++  while (*input)
++    {
++      if (*input == ch)
++      {
++        grub_strcpy (output, with);
++        output += grub_strlen (with);
++        input++;
++        continue;
++      }
++      *output++ = *input++;
++    }
++  *output = '\0';
++  return output;
++}
++
++extern void (*EXPORT_VAR (grub_xputs)) (const char *str);
++
++static inline int
++grub_puts (const char *s)
++{
++  const char nl[2] = "\n";
++  grub_xputs (s);
++  grub_xputs (nl);
++
++  return 1;   /* Cannot fail.  */
++}
++
++int EXPORT_FUNC(grub_puts_) (const char *s);
++void EXPORT_FUNC(grub_real_dprintf) (const char *file,
++                                     const int line,
++                                     const char *condition,
++                                     const char *fmt, ...) __attribute__ 
((format (GNU_PRINTF, 4, 5)));
++int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args);
++int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, 
...)
++     __attribute__ ((format (GNU_PRINTF, 3, 4)));
++int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt,
++                               va_list args);
++char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...)
++     __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT;
++char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) 
WARN_UNUSED_RESULT;
++void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
++grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
++                                        grub_uint64_t d,
++                                        grub_uint64_t *r);
++
++#if (defined (__MINGW32__) || defined (__CYGWIN__)) && !defined(GRUB_UTIL)
++void EXPORT_FUNC (__register_frame_info) (void);
++void EXPORT_FUNC (__deregister_frame_info) (void);
++void EXPORT_FUNC (___chkstk_ms) (void);
++void EXPORT_FUNC (__chkstk_ms) (void);
++#endif
++
++/* Inline functions.  */
++
++static inline char *
++grub_memchr (const void *p, int c, grub_size_t len)
++{
++  const char *s = (const char *) p;
++  const char *e = s + len;
++
++  for (; s < e; s++)
++    if (*s == c)
++      return (char *) s;
++
++  return 0;
++}
++
++
++static inline unsigned int
++grub_abs (int x)
++{
++  if (x < 0)
++    return (unsigned int) (-x);
++  else
++    return (unsigned int) x;
++}
++
++/* Rounded-up division */
++static inline unsigned int
++grub_div_roundup (unsigned int x, unsigned int y)
++{
++  return (x + y - 1) / y;
++}
++
++/* Reboot the machine.  */
++#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS)
++void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn));
++#else
++void grub_reboot (void) __attribute__ ((noreturn));
++#endif
++
++#if defined (__clang__) && !defined (GRUB_UTIL)
++void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void);
++#endif
++
++#ifdef GRUB_MACHINE_PCBIOS
++/* Halt the system, using APM if possible. If NO_APM is true, don't
++ * use APM even if it is available.  */
++void grub_halt (int no_apm) __attribute__ ((noreturn));
++#elif defined (__mips__) && !defined (GRUB_MACHINE_EMU)
++void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn));
++#else
++void grub_halt (void) __attribute__ ((noreturn));
++#endif
++
++#ifdef GRUB_MACHINE_EMU
++/* Flag to check if module loading is available.  */
++extern const int EXPORT_VAR(grub_no_modules);
++#else
++#define grub_no_modules 0
++#endif
++
++static inline void
++grub_error_save (struct grub_error_saved *save)
++{
++  grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg));
++  save->grub_errno = grub_errno;
++  grub_errno = GRUB_ERR_NONE;
++}
++
++static inline void
++grub_error_load (const struct grub_error_saved *save)
++{
++  grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg));
++  grub_errno = save->grub_errno;
++}
++
++#ifndef GRUB_UTIL
++
++#if defined (__arm__)
++
++grub_uint32_t
++EXPORT_FUNC (__udivsi3) (grub_uint32_t a, grub_uint32_t b);
++
++grub_uint32_t
++EXPORT_FUNC (__umodsi3) (grub_uint32_t a, grub_uint32_t b);
++
++#endif
++
++#if defined (__sparc__) || defined (__powerpc__)
++unsigned
++EXPORT_FUNC (__ctzdi2) (grub_uint64_t x);
++#define NEED_CTZDI2 1
++#endif
++
++#if defined (__mips__) || defined (__arm__)
++unsigned
++EXPORT_FUNC (__ctzsi2) (grub_uint32_t x);
++#define NEED_CTZSI2 1
++#endif
++
++#ifdef __arm__
++grub_uint32_t
++EXPORT_FUNC (__aeabi_uidiv) (grub_uint32_t a, grub_uint32_t b);
++grub_uint32_t
++EXPORT_FUNC (__aeabi_uidivmod) (grub_uint32_t a, grub_uint32_t b);
++
++/* Needed for allowing modules to be compiled as thumb.  */
++grub_uint64_t
++EXPORT_FUNC (__muldi3) (grub_uint64_t a, grub_uint64_t b);
++grub_uint64_t
++EXPORT_FUNC (__aeabi_lmul) (grub_uint64_t a, grub_uint64_t b);
++
++#endif
++
++#if defined (__ia64__)
++
++grub_uint64_t
++EXPORT_FUNC (__udivdi3) (grub_uint64_t a, grub_uint64_t b);
++
++grub_uint64_t
++EXPORT_FUNC (__umoddi3) (grub_uint64_t a, grub_uint64_t b);
++
++#endif
++
++#endif /* GRUB_UTIL */
++
++
++#if BOOT_TIME_STATS
++struct grub_boot_time
++{
++  struct grub_boot_time *next;
++  grub_uint64_t tp;
++  const char *file;
++  int line;
++  char *msg;
++};
++
++extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head);
++
++void EXPORT_FUNC(grub_real_boot_time) (const char *file,
++                                     const int line,
++                                     const char *fmt, ...) __attribute__ 
((format (GNU_PRINTF, 3, 4)));
++#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, 
__VA_ARGS__)
++#else
++#define grub_boot_time(...)
++#endif
++
++#define grub_max(a, b) (((a) > (b)) ? (a) : (b))
++#define grub_min(a, b) (((a) < (b)) ? (a) : (b))
++
++#endif /* ! GRUB_MISC_HEADER */
+diff --git a/i386/grub/mm.h b/i386/grub/mm.h
+new file mode 100644
+index 0000000..28e2e53
+--- /dev/null
++++ b/i386/grub/mm.h
+@@ -0,0 +1,77 @@
++/* mm.h - prototypes and declarations for memory manager */
++/*
++ *  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_MM_H
++#define GRUB_MM_H     1
++
++#include <grub/types.h>
++#include <grub/symbol.h>
++#include <config.h>
++
++#ifndef NULL
++# define NULL ((void *) 0)
++#endif
++
++void grub_mm_init_region (void *addr, grub_size_t size);
++void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
++void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
++void EXPORT_FUNC(grub_free) (void *ptr);
++void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
++#ifndef GRUB_MACHINE_EMU
++void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
++#endif
++
++void grub_mm_check_real (const char *file, int line);
++#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
++
++/* For debugging.  */
++#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
++/* Set this variable to 1 when you want to trace all memory function calls.  
*/
++extern int EXPORT_VAR(grub_mm_debug);
++
++void grub_mm_dump_free (void);
++void grub_mm_dump (unsigned lineno);
++
++#define grub_malloc(size)     \
++  grub_debug_malloc (GRUB_FILE, __LINE__, size)
++
++#define grub_zalloc(size)     \
++  grub_debug_zalloc (GRUB_FILE, __LINE__, size)
++
++#define grub_realloc(ptr,size)        \
++  grub_debug_realloc (GRUB_FILE, __LINE__, ptr, size)
++
++#define grub_memalign(align,size)     \
++  grub_debug_memalign (GRUB_FILE, __LINE__, align, size)
++
++#define grub_free(ptr)        \
++  grub_debug_free (GRUB_FILE, __LINE__, ptr)
++
++void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
++                                    grub_size_t size);
++void *EXPORT_FUNC(grub_debug_zalloc) (const char *file, int line,
++                                     grub_size_t size);
++void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
++void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
++                                     grub_size_t size);
++void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
++                                      grub_size_t align, grub_size_t size);
++#endif /* MM_DEBUG && ! GRUB_UTIL */
++
++#endif /* ! GRUB_MM_H */
+diff --git a/i386/grub/symbol.h b/i386/grub/symbol.h
+new file mode 100644
+index 0000000..ed19f70
+--- /dev/null
++++ b/i386/grub/symbol.h
+@@ -0,0 +1,72 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 1999,2000,2001,2002,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_SYMBOL_HEADER
++#define GRUB_SYMBOL_HEADER    1
++
++#include <config.h>
++
++/* Apple assembler requires local labels to start with a capital L */
++#define LOCAL(sym)    L_ ## sym
++
++/* Add an underscore to a C symbol in assembler code if needed. */
++#ifndef GRUB_UTIL
++
++#ifdef __APPLE__
++#define MACRO_DOLLAR(x) $$ ## x
++#else
++#define MACRO_DOLLAR(x) $ ## x
++#endif
++
++#if HAVE_ASM_USCORE
++#ifdef ASM_FILE
++# define EXT_C(sym)   _ ## sym
++#else
++# define EXT_C(sym)   "_" sym
++#endif
++#else
++# define EXT_C(sym)   sym
++#endif
++
++#ifdef __arm__
++#define END .end
++#endif
++
++#if defined (__APPLE__)
++#define FUNCTION(x)   .globl EXT_C(x) ; EXT_C(x):
++#define VARIABLE(x)   .globl EXT_C(x) ; EXT_C(x):
++#elif defined (__CYGWIN__) || defined (__MINGW32__)
++/* .type not supported for non-ELF targets.  XXX: Check this in configure? */
++#define FUNCTION(x)   .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 32; 
.endef; EXT_C(x):
++#define VARIABLE(x)   .globl EXT_C(x) ; .def EXT_C(x); .scl 2; .type 0; 
.endef; EXT_C(x):
++#elif defined (__arm__)
++#define FUNCTION(x)   .globl EXT_C(x) ; .type EXT_C(x), %function ; EXT_C(x):
++#define VARIABLE(x)   .globl EXT_C(x) ; .type EXT_C(x), %object ; EXT_C(x):
++#else
++#define FUNCTION(x)   .globl EXT_C(x) ; .type EXT_C(x), @function ; EXT_C(x):
++#define VARIABLE(x)   .globl EXT_C(x) ; .type EXT_C(x), @object ; EXT_C(x):
++#endif
++#endif
++
++/* Mark an exported symbol.  */
++#ifndef GRUB_SYMBOL_GENERATOR
++# define EXPORT_FUNC(x)       x
++# define EXPORT_VAR(x)        x
++#endif /* ! GRUB_SYMBOL_GENERATOR */
++
++#endif /* ! GRUB_SYMBOL_HEADER */
+diff --git a/i386/grub/time.h b/i386/grub/time.h
+new file mode 100644
+index 0000000..64ac99a
+--- /dev/null
++++ b/i386/grub/time.h
+@@ -0,0 +1,46 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2007, 2008  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 KERNEL_TIME_HEADER
++#define KERNEL_TIME_HEADER    1
++
++#include <grub/types.h>
++#include <grub/symbol.h>
++#ifndef GRUB_MACHINE_EMU
++#include <grub/cpu/time.h>
++#else
++static inline void
++grub_cpu_idle(void)
++{
++}
++#endif
++
++void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms);
++grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void);
++
++grub_uint64_t grub_rtc_get_time_ms (void);
++
++static __inline void
++grub_sleep (grub_uint32_t s)
++{
++  grub_millisleep (1000 * s);
++}
++
++void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void));
++
++#endif /* ! KERNEL_TIME_HEADER */
+diff --git a/i386/grub/types.h b/i386/grub/types.h
+new file mode 100644
+index 0000000..79f765c
+--- /dev/null
++++ b/i386/grub/types.h
+@@ -0,0 +1,325 @@
++/*
++ *  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_TYPES_HEADER
++#define GRUB_TYPES_HEADER     1
++
++#include <config.h>
++#ifndef GRUB_UTIL
++#include <grub/cpu/types.h>
++#endif
++
++#ifdef __MINGW32__
++#define GRUB_PACKED __attribute__ ((packed,gcc_struct))
++#else
++#define GRUB_PACKED __attribute__ ((packed))
++#endif
++
++#ifdef GRUB_BUILD
++# define GRUB_CPU_SIZEOF_VOID_P       BUILD_SIZEOF_VOID_P
++# define GRUB_CPU_SIZEOF_LONG BUILD_SIZEOF_LONG
++# if BUILD_WORDS_BIGENDIAN
++#  define GRUB_CPU_WORDS_BIGENDIAN    1
++# else
++#  undef GRUB_CPU_WORDS_BIGENDIAN
++# endif
++#elif defined (GRUB_UTIL)
++# define GRUB_CPU_SIZEOF_VOID_P       SIZEOF_VOID_P
++# define GRUB_CPU_SIZEOF_LONG SIZEOF_LONG
++# ifdef WORDS_BIGENDIAN
++#  define GRUB_CPU_WORDS_BIGENDIAN    1
++# else
++#  undef GRUB_CPU_WORDS_BIGENDIAN
++# endif
++#else /* ! GRUB_UTIL */
++# define GRUB_CPU_SIZEOF_VOID_P       GRUB_TARGET_SIZEOF_VOID_P
++# define GRUB_CPU_SIZEOF_LONG GRUB_TARGET_SIZEOF_LONG
++# ifdef GRUB_TARGET_WORDS_BIGENDIAN
++#  define GRUB_CPU_WORDS_BIGENDIAN    1
++# else
++#  undef GRUB_CPU_WORDS_BIGENDIAN
++# endif
++#endif /* ! GRUB_UTIL */
++
++#if GRUB_CPU_SIZEOF_VOID_P != 4 && GRUB_CPU_SIZEOF_VOID_P != 8
++# error "This architecture is not supported because sizeof(void *) != 4 and 
sizeof(void *) != 8"
++#endif
++
++#if GRUB_CPU_SIZEOF_LONG != 4 && GRUB_CPU_SIZEOF_LONG != 8
++# error "This architecture is not supported because sizeof(long) != 4 and 
sizeof(long) != 8"
++#endif
++
++#if !defined (GRUB_UTIL) && !defined (GRUB_TARGET_WORDSIZE)
++# if GRUB_TARGET_SIZEOF_VOID_P == 4
++#  define GRUB_TARGET_WORDSIZE 32
++# elif GRUB_TARGET_SIZEOF_VOID_P == 8
++#  define GRUB_TARGET_WORDSIZE 64
++# endif
++#endif
++
++/* Define various wide integers.  */
++typedef signed char           grub_int8_t;
++typedef short                 grub_int16_t;
++typedef int                   grub_int32_t;
++#if GRUB_CPU_SIZEOF_LONG == 8
++typedef long                  grub_int64_t;
++#else
++typedef long long             grub_int64_t;
++#endif
++
++typedef unsigned char         grub_uint8_t;
++typedef unsigned short                grub_uint16_t;
++typedef unsigned              grub_uint32_t;
++# define PRIxGRUB_UINT32_T    "x"
++# define PRIuGRUB_UINT32_T    "u"
++#if GRUB_CPU_SIZEOF_LONG == 8
++typedef unsigned long         grub_uint64_t;
++# define PRIxGRUB_UINT64_T    "lx"
++# define PRIuGRUB_UINT64_T    "lu"
++#else
++typedef unsigned long long    grub_uint64_t;
++# define PRIxGRUB_UINT64_T    "llx"
++# define PRIuGRUB_UINT64_T    "llu"
++#endif
++
++/* Misc types.  */
++
++#if GRUB_CPU_SIZEOF_VOID_P == 8
++typedef grub_uint64_t grub_addr_t;
++typedef grub_uint64_t grub_size_t;
++typedef grub_int64_t  grub_ssize_t;
++
++# define GRUB_SIZE_MAX 18446744073709551615UL
++
++# if GRUB_CPU_SIZEOF_LONG == 8
++#  define PRIxGRUB_SIZE        "lx"
++#  define PRIxGRUB_ADDR        "lx"
++#  define PRIuGRUB_SIZE        "lu"
++#  define PRIdGRUB_SSIZE "ld"
++# else
++#  define PRIxGRUB_SIZE        "llx"
++#  define PRIxGRUB_ADDR        "llx"
++#  define PRIuGRUB_SIZE  "llu"
++#  define PRIdGRUB_SSIZE "lld"
++# endif
++#else
++typedef grub_uint32_t grub_addr_t;
++typedef grub_uint32_t grub_size_t;
++typedef grub_int32_t  grub_ssize_t;
++
++# define GRUB_SIZE_MAX 4294967295UL
++
++# define PRIxGRUB_SIZE        "x"
++# define PRIxGRUB_ADDR        "x"
++# define PRIuGRUB_SIZE        "u"
++# define PRIdGRUB_SSIZE       "d"
++#endif
++
++#define GRUB_UCHAR_MAX 0xFF
++#define GRUB_USHRT_MAX 65535
++#define GRUB_SHRT_MAX 0x7fff
++#define GRUB_UINT_MAX 4294967295U
++#define GRUB_INT_MAX 0x7fffffff
++#define GRUB_INT32_MIN (-2147483647 - 1)
++#define GRUB_INT32_MAX 2147483647
++
++#if GRUB_CPU_SIZEOF_LONG == 8
++# define GRUB_ULONG_MAX 18446744073709551615UL
++# define GRUB_LONG_MAX 9223372036854775807L
++# define GRUB_LONG_MIN (-9223372036854775807L - 1)
++#else
++# define GRUB_ULONG_MAX 4294967295UL
++# define GRUB_LONG_MAX 2147483647L
++# define GRUB_LONG_MIN (-2147483647L - 1)
++#endif
++
++typedef grub_uint64_t grub_properly_aligned_t;
++
++#define GRUB_PROPERLY_ALIGNED_ARRAY(name, size) grub_properly_aligned_t 
name[((size) + sizeof (grub_properly_aligned_t) - 1) / sizeof 
(grub_properly_aligned_t)]
++
++/* The type for representing a file offset.  */
++typedef grub_uint64_t grub_off_t;
++
++/* The type for representing a disk block address.  */
++typedef grub_uint64_t grub_disk_addr_t;
++
++/* Byte-orders.  */
++static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x)
++{
++   return (grub_uint16_t) ((_x << 8) | (_x >> 8));
++}
++
++#define grub_swap_bytes16_compile_time(x) ((((x) & 0xff) << 8) | (((x) & 
0xff00) >> 8))
++#define grub_swap_bytes32_compile_time(x) ((((x) & 0xff) << 24) | (((x) & 
0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24))
++#define grub_swap_bytes64_compile_time(x)     \
++({ \
++   grub_uint64_t _x = (x); \
++   (grub_uint64_t) ((_x << 56) \
++                    | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \
++                    | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \
++                    | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \
++                    | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \
++                    | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \
++                    | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \
++                    | (_x >> 56)); \
++})
++
++#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 
3)
++static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t x)
++{
++      return __builtin_bswap32(x);
++}
++
++static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x)
++{
++      return __builtin_bswap64(x);
++}
++#else                                 /* not gcc 4.3 or newer */
++static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t _x)
++{
++   return ((_x << 24)
++         | ((_x & (grub_uint32_t) 0xFF00UL) << 8)
++         | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8)
++         | (_x >> 24));
++}
++
++static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t _x)
++{
++   return ((_x << 56)
++         | ((_x & (grub_uint64_t) 0xFF00ULL) << 40)
++         | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24)
++         | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8)
++         | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8)
++         | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24)
++         | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40)
++         | (_x >> 56));
++}
++#endif                                        /* not gcc 4.3 or newer */
++
++#ifdef GRUB_CPU_WORDS_BIGENDIAN
++# define grub_cpu_to_le16(x)  grub_swap_bytes16(x)
++# define grub_cpu_to_le32(x)  grub_swap_bytes32(x)
++# define grub_cpu_to_le64(x)  grub_swap_bytes64(x)
++# define grub_le_to_cpu16(x)  grub_swap_bytes16(x)
++# define grub_le_to_cpu32(x)  grub_swap_bytes32(x)
++# define grub_le_to_cpu64(x)  grub_swap_bytes64(x)
++# define grub_cpu_to_be16(x)  ((grub_uint16_t) (x))
++# define grub_cpu_to_be32(x)  ((grub_uint32_t) (x))
++# define grub_cpu_to_be64(x)  ((grub_uint64_t) (x))
++# define grub_be_to_cpu16(x)  ((grub_uint16_t) (x))
++# define grub_be_to_cpu32(x)  ((grub_uint32_t) (x))
++# define grub_be_to_cpu64(x)  ((grub_uint64_t) (x))
++# define grub_cpu_to_be16_compile_time(x)     ((grub_uint16_t) (x))
++# define grub_cpu_to_be32_compile_time(x)     ((grub_uint32_t) (x))
++# define grub_cpu_to_be64_compile_time(x)     ((grub_uint64_t) (x))
++# define grub_be_to_cpu64_compile_time(x)     ((grub_uint64_t) (x))
++# define grub_cpu_to_le32_compile_time(x)     
grub_swap_bytes32_compile_time(x)
++# define grub_cpu_to_le64_compile_time(x)     
grub_swap_bytes64_compile_time(x)
++# define grub_cpu_to_le16_compile_time(x)     
grub_swap_bytes16_compile_time(x)
++#else /* ! WORDS_BIGENDIAN */
++# define grub_cpu_to_le16(x)  ((grub_uint16_t) (x))
++# define grub_cpu_to_le32(x)  ((grub_uint32_t) (x))
++# define grub_cpu_to_le64(x)  ((grub_uint64_t) (x))
++# define grub_le_to_cpu16(x)  ((grub_uint16_t) (x))
++# define grub_le_to_cpu32(x)  ((grub_uint32_t) (x))
++# define grub_le_to_cpu64(x)  ((grub_uint64_t) (x))
++# define grub_cpu_to_be16(x)  grub_swap_bytes16(x)
++# define grub_cpu_to_be32(x)  grub_swap_bytes32(x)
++# define grub_cpu_to_be64(x)  grub_swap_bytes64(x)
++# define grub_be_to_cpu16(x)  grub_swap_bytes16(x)
++# define grub_be_to_cpu32(x)  grub_swap_bytes32(x)
++# define grub_be_to_cpu64(x)  grub_swap_bytes64(x)
++# define grub_cpu_to_be16_compile_time(x)     
grub_swap_bytes16_compile_time(x)
++# define grub_cpu_to_be32_compile_time(x)     
grub_swap_bytes32_compile_time(x)
++# define grub_cpu_to_be64_compile_time(x)     
grub_swap_bytes64_compile_time(x)
++# define grub_be_to_cpu64_compile_time(x)     
grub_swap_bytes64_compile_time(x)
++# define grub_cpu_to_le16_compile_time(x)     ((grub_uint16_t) (x))
++# define grub_cpu_to_le32_compile_time(x)     ((grub_uint32_t) (x))
++# define grub_cpu_to_le64_compile_time(x)     ((grub_uint64_t) (x))
++
++#endif /* ! WORDS_BIGENDIAN */
++
++static inline grub_uint16_t grub_get_unaligned16 (const void *ptr)
++{
++  struct grub_unaligned_uint16_t
++  {
++    grub_uint16_t d;
++  } GRUB_PACKED;
++  const struct grub_unaligned_uint16_t *dd
++    = (const struct grub_unaligned_uint16_t *) ptr;
++  return dd->d;
++}
++
++static inline void grub_set_unaligned16 (void *ptr, grub_uint16_t val)
++{
++  struct grub_unaligned_uint16_t
++  {
++    grub_uint16_t d;
++  } GRUB_PACKED;
++  struct grub_unaligned_uint16_t *dd = (struct grub_unaligned_uint16_t *) ptr;
++  dd->d = val;
++}
++
++static inline grub_uint32_t grub_get_unaligned32 (const void *ptr)
++{
++  struct grub_unaligned_uint32_t
++  {
++    grub_uint32_t d;
++  } GRUB_PACKED;
++  const struct grub_unaligned_uint32_t *dd
++    = (const struct grub_unaligned_uint32_t *) ptr;
++  return dd->d;
++}
++
++static inline void grub_set_unaligned32 (void *ptr, grub_uint32_t val)
++{
++  struct grub_unaligned_uint32_t
++  {
++    grub_uint32_t d;
++  } GRUB_PACKED;
++  struct grub_unaligned_uint32_t *dd = (struct grub_unaligned_uint32_t *) ptr;
++  dd->d = val;
++}
++
++struct grub_unaligned_uint64
++{
++  grub_uint64_t val;
++} GRUB_PACKED;
++
++typedef struct grub_unaligned_uint64 grub_unaligned_uint64_t;
++
++static inline grub_uint64_t grub_get_unaligned64 (const void *ptr)
++{
++  const struct grub_unaligned_uint64 *dd
++    = (const struct grub_unaligned_uint64 *) ptr;
++  return dd->val;
++}
++
++static inline void grub_set_unaligned64 (void *ptr, grub_uint64_t val)
++{
++  struct grub_unaligned_uint64_t
++  {
++    grub_uint64_t d;
++  } GRUB_PACKED;
++  struct grub_unaligned_uint64_t *dd = (struct grub_unaligned_uint64_t *) ptr;
++  dd->d = val;
++}
++
++#define GRUB_CHAR_BIT 8
++
++#endif /* ! GRUB_TYPES_HEADER */
+diff --git a/i386/i386at/acpi.c b/i386/i386at/acpi.c
+new file mode 100644
+index 0000000..ec8aeb1
+--- /dev/null
++++ b/i386/i386at/acpi.c
+@@ -0,0 +1,82 @@
++/* acpi.c - get acpi tables. */
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 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/>.
++ */
++
++#include <grub/glue.h>
++#include <grub/acpi.h>
++#include <grub/misc.h>
++
++struct grub_acpi_rsdp_v10 *
++grub_machine_acpi_get_rsdpv1 (void)
++{
++  int ebda_len;
++  grub_uint8_t *ebda, *ptr;
++
++  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
++  ebda = (grub_uint8_t *) phystokv ((* ((grub_uint16_t *) phystokv (0x40e))) 
<< 4);
++  ebda_len = * (grub_uint16_t *) ebda;
++  if (! ebda_len)
++    return 0;
++  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
++    if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
++      && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
++      && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
++      return (struct grub_acpi_rsdp_v10 *) ptr;
++
++  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
++  for (ptr = (grub_uint8_t *) phystokv (0xe0000); ptr < (grub_uint8_t *) 
phystokv (0x100000);
++       ptr += 16)
++    if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
++      && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
++      && ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
++      return (struct grub_acpi_rsdp_v10 *) ptr;
++  return 0;
++}
++
++struct grub_acpi_rsdp_v20 *
++grub_machine_acpi_get_rsdpv2 (void)
++{
++  int ebda_len;
++  grub_uint8_t *ebda, *ptr;
++
++  grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
++  ebda = (grub_uint8_t *) phystokv ((* ((grub_uint16_t *) phystokv (0x40e))) 
<< 4);
++  ebda_len = * (grub_uint16_t *) ebda;
++  if (! ebda_len)
++    return 0;
++  for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
++    if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
++      && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
++      && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
++      && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
++      && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
++      == 0)
++      return (struct grub_acpi_rsdp_v20 *) ptr;
++
++  grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
++  for (ptr = (grub_uint8_t *) phystokv (0xe0000); ptr < (grub_uint8_t *) 
phystokv (0x100000);
++       ptr += 16)
++    if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) == 0
++      && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) == 0
++      && ((struct grub_acpi_rsdp_v10 *) ptr)->revision != 0
++      && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024
++      && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length)
++      == 0)
++      return (struct grub_acpi_rsdp_v20 *) ptr;
++  return 0;
++}
+diff --git a/i386/i386at/acpihalt.c b/i386/i386at/acpihalt.c
+new file mode 100644
+index 0000000..23df44f
+--- /dev/null
++++ b/i386/i386at/acpihalt.c
+@@ -0,0 +1,409 @@
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2010  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/glue.h>
++
++#ifdef GRUB_DSDT_TEST
++#include <stdio.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <stdint.h>
++#include <string.h>
++#include <errno.h>
++
++#define grub_dprintf(cond, args...) printf ( args )
++#define grub_printf printf
++typedef uint64_t grub_uint64_t;
++typedef uint32_t grub_uint32_t;
++typedef uint16_t grub_uint16_t;
++typedef uint8_t grub_uint8_t;
++
++#endif
++
++#include <grub/acpi.h>
++#ifndef GRUB_DSDT_TEST
++#include <grub/i18n.h>
++#else
++#define _(x) x
++#define N_(x) x
++#endif
++
++#ifndef GRUB_DSDT_TEST
++#include <grub/mm.h>
++#include <grub/misc.h>
++#include <grub/time.h>
++#include <grub/cpu/io.h>
++#endif
++
++static inline grub_uint32_t
++decode_length (const grub_uint8_t *ptr, int *numlen)
++{
++  int num_bytes, i;
++  grub_uint32_t ret;
++  if (*ptr < 64)
++    {
++      if (numlen)
++      *numlen = 1;
++      return *ptr;
++    }
++  num_bytes = *ptr >> 6;
++  if (numlen)
++    *numlen = num_bytes + 1;
++  ret = *ptr & 0xf;
++  ptr++;
++  for (i = 0; i < num_bytes; i++)
++    {
++      ret |= *ptr << (8 * i + 4);
++      ptr++;
++    }
++  return ret;
++}
++
++static inline grub_uint32_t
++skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end)
++{
++  const grub_uint8_t *ptr0 = ptr;
++  
++  while (ptr < end && (*ptr == '^' || *ptr == '\\'))
++    ptr++;
++  switch (*ptr)
++    {
++    case '.':
++      ptr++;
++      ptr += 8;
++      break;
++    case '/':
++      ptr++;
++      ptr += 1 + (*ptr) * 4;
++      break;
++    case 0:
++      ptr++;
++      break;
++    default:
++      ptr += 4;
++      break;
++    }
++  return ptr - ptr0;
++}
++
++static inline grub_uint32_t
++skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
++{
++  grub_dprintf ("acpi", "data type = 0x%x\n", *ptr);
++  switch (*ptr)
++    {
++    case GRUB_ACPI_OPCODE_PACKAGE:
++    case GRUB_ACPI_OPCODE_BUFFER:
++      return 1 + decode_length (ptr + 1, 0);
++    case GRUB_ACPI_OPCODE_ZERO:
++    case GRUB_ACPI_OPCODE_ONES:
++    case GRUB_ACPI_OPCODE_ONE:
++      return 1;
++    case GRUB_ACPI_OPCODE_BYTE_CONST:
++      return 2;
++    case GRUB_ACPI_OPCODE_WORD_CONST:
++      return 3;
++    case GRUB_ACPI_OPCODE_DWORD_CONST:
++      return 5;
++    case GRUB_ACPI_OPCODE_STRING_CONST:
++      {
++      const grub_uint8_t *ptr0 = ptr;
++      for (ptr++; ptr < end && *ptr; ptr++);
++      if (ptr == end)
++        return 0;
++      return ptr - ptr0 + 1;
++      }
++    default:
++      if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
++        || (*ptr >= 'A' && *ptr <= 'Z'))
++      return skip_name_string (ptr, end);
++      grub_printf ("Unknown opcode 0x%x\n", *ptr);
++      return 0;
++    }
++}
++
++static inline grub_uint32_t
++skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
++{
++  const grub_uint8_t *ptr0 = ptr;
++  int add;
++  grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
++  switch (*ptr)
++    {
++    case GRUB_ACPI_EXTOPCODE_MUTEX:
++      ptr++;
++      ptr += skip_name_string (ptr, end);
++      ptr++;
++      break;
++    case GRUB_ACPI_EXTOPCODE_EVENT_OP:
++      ptr++;
++      ptr += skip_name_string (ptr, end);
++      break;
++    case GRUB_ACPI_EXTOPCODE_OPERATION_REGION:
++      ptr++;
++      ptr += skip_name_string (ptr, end);
++      ptr++;
++      ptr += add = skip_data_ref_object (ptr, end);
++      if (!add)
++      return 0;
++      ptr += add = skip_data_ref_object (ptr, end);
++      if (!add)
++      return 0;
++      break;
++    case GRUB_ACPI_EXTOPCODE_FIELD_OP:
++    case GRUB_ACPI_EXTOPCODE_DEVICE_OP:
++    case GRUB_ACPI_EXTOPCODE_PROCESSOR_OP:
++    case GRUB_ACPI_EXTOPCODE_POWER_RES_OP:
++    case GRUB_ACPI_EXTOPCODE_THERMAL_ZONE_OP:
++    case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP:
++    case GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP:
++      ptr++;
++      ptr += decode_length (ptr, 0);
++      break;
++    default:
++      grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
++      return 0;
++    }
++  return ptr - ptr0;
++}
++
++static int
++get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
++              grub_uint8_t *scope, int scope_len)
++{
++  grub_uint8_t *prev = table;
++  
++  if (!ptr)
++    ptr = table + sizeof (struct grub_acpi_table_header);
++  while (ptr < end && prev < ptr)
++    {
++      int add;
++      prev = ptr;
++      grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
++      grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
++      switch (*ptr)
++      {
++      case GRUB_ACPI_OPCODE_EXTOP:
++        ptr++;
++        ptr += add = skip_ext_op (ptr, end);
++        if (!add)
++          return -1;
++        break;
++      case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
++      case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
++        {
++          ptr += 5;
++          ptr += add = skip_data_ref_object (ptr, end);
++          if (!add)
++            return -1;
++          ptr += 4;
++          break;
++        }
++      case GRUB_ACPI_OPCODE_NAME:
++        ptr++;
++        if ((!scope || grub_memcmp (scope, "\\", scope_len) == 0) &&
++            (grub_memcmp (ptr, "_S5_", 4) == 0 || grub_memcmp (ptr, "\\_S5_", 
4) == 0))
++          {
++            int ll;
++            grub_uint8_t *ptr2 = ptr;
++            grub_dprintf ("acpi", "S5 found\n");
++            ptr2 += skip_name_string (ptr, end);
++            if (*ptr2 != 0x12)
++              {
++                grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
++                return -1;
++              }
++            ptr2++;
++            decode_length (ptr2, &ll);
++            ptr2 += ll;
++            ptr2++;
++            switch (*ptr2)
++              {
++              case GRUB_ACPI_OPCODE_ZERO:
++                return 0;
++              case GRUB_ACPI_OPCODE_ONE:
++                return 1;
++              case GRUB_ACPI_OPCODE_BYTE_CONST:
++                return ptr2[1];
++              default:
++                grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
++                return -1;
++              }
++          }
++        ptr += add = skip_name_string (ptr, end);
++        if (!add)
++          return -1;
++        ptr += add = skip_data_ref_object (ptr, end);
++        if (!add)
++          return -1;
++        break;
++      case GRUB_ACPI_OPCODE_SCOPE:
++        {
++          int scope_sleep_type;
++          int ll;
++          grub_uint8_t *name;
++          int name_len;
++
++          ptr++;
++          add = decode_length (ptr, &ll);
++          name = ptr + ll;
++          name_len = skip_name_string (name, ptr + add);
++          if (!name_len)
++            return -1;
++          scope_sleep_type = get_sleep_type (table, name + name_len,
++                                             ptr + add, name, name_len);
++          if (scope_sleep_type != -2)
++            return scope_sleep_type;
++          ptr += add;
++          break;
++        }
++      case GRUB_ACPI_OPCODE_IF:
++      case GRUB_ACPI_OPCODE_METHOD:
++        {
++          ptr++;
++          ptr += decode_length (ptr, 0);
++          break;
++        }
++      default:
++        grub_printf ("Unknown opcode 0x%x\n", *ptr);
++        return -1;      
++      }
++    }
++
++  return -2;
++}
++
++#ifdef GRUB_DSDT_TEST
++int
++main (int argc, char **argv)
++{
++  FILE *f;
++  size_t len;
++  unsigned char *buf;
++  if (argc < 2)
++    printf ("Usage: %s FILE\n", argv[0]);
++  f = grub_util_fopen (argv[1], "rb");
++  if (!f)
++    {
++      printf ("Couldn't open file\n");
++      return 1;
++    }
++  fseek (f, 0, SEEK_END);
++  len = ftell (f);
++  fseek (f, 0, SEEK_SET);
++  buf = malloc (len);
++  if (!buf)
++    {
++      printf (_("error: %s.\n"), _("out of memory"));
++      fclose (f);
++      return 2;
++    }
++  if (fread (buf, 1, len, f) != len)
++    {
++      printf (_("cannot read `%s': %s"), argv[1], strerror (errno));
++      free (buf);
++      fclose (f);
++      return 2;
++    }
++
++  printf ("Sleep type = %d\n", get_sleep_type (buf, NULL, buf + len, NULL, 
0));
++  free (buf);
++  fclose (f);
++  return 0;
++}
++
++#else
++
++void
++grub_acpi_halt (void)
++{
++  struct grub_acpi_rsdp_v20 *rsdp2;
++  struct grub_acpi_rsdp_v10 *rsdp1;
++  struct grub_acpi_table_header *rsdt;
++  grub_uint32_t *entry_ptr;
++  grub_uint32_t port = 0;
++  int sleep_type = -1;
++
++  rsdp2 = grub_acpi_get_rsdpv2 ();
++  if (rsdp2)
++    rsdp1 = &(rsdp2->rsdpv1);
++  else
++    rsdp1 = grub_acpi_get_rsdpv1 ();
++  grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
++  if (!rsdp1)
++    return;
++
++  rsdt = (struct grub_acpi_table_header *)
++    io_map_cached (rsdp1->rsdt_addr, sizeof *rsdt);
++  rsdt = (struct grub_acpi_table_header *)
++    io_map_cached (rsdp1->rsdt_addr, rsdt->length);
++
++  for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
++       entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
++                                    + rsdt->length);
++       entry_ptr++)
++    {
++      if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4),
++                     "FACP", 4) == 0)
++      {
++        struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *)
++          io_map_cached (*entry_ptr, sizeof *fadt);
++
++        struct grub_acpi_table_header *dsdt =
++          (struct grub_acpi_table_header *)
++          io_map_cached (fadt->dsdt_addr, sizeof *dsdt);
++        grub_uint8_t *buf = (grub_uint8_t *)
++          io_map_cached (fadt->dsdt_addr, dsdt->length);
++
++        port = fadt->pm1a;
++
++        grub_dprintf ("acpi", "PM1a port=%x\n", port);
++
++        if (grub_memcmp (dsdt->signature, "DSDT",
++                         sizeof (dsdt->signature)) == 0
++            && sleep_type < 0)
++          sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length,
++                                       NULL, 0);
++      }
++      else
++      if (grub_memcmp ((void *) io_map_cached (*entry_ptr, 4), "SSDT", 4) == 0
++          && sleep_type < 0)
++      {
++        struct grub_acpi_table_header *ssdt
++          = (struct grub_acpi_table_header *) (grub_addr_t)
++          io_map_cached (*entry_ptr, sizeof *ssdt);
++        grub_uint8_t *buf = (grub_uint8_t *)
++          io_map_cached (*entry_ptr, ssdt->length);
++
++        grub_dprintf ("acpi", "SSDT = %p\n", ssdt);
++
++        sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0);
++      }
++    }
++
++  grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port);
++  if (port && sleep_type >= 0 && sleep_type < 8)
++    grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET),
++             port & 0xffff);
++
++  grub_millisleep (1500);
++
++  /* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI.  */
++  grub_puts_ (N_("ACPI shutdown failed"));
++}
++#endif
+diff --git a/i386/i386at/acpihalt.h b/i386/i386at/acpihalt.h
+new file mode 100644
+index 0000000..a4fdb07
+--- /dev/null
++++ b/i386/i386at/acpihalt.h
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (c) 2014 Free Software Foundation.
++ *
++ * 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 _ACPIHALT_H_
++#define _ACPIHALT_H_
++
++void grub_acpi_halt (void);
++
++#endif /* _ACPIHALT_H_ */
+diff --git a/i386/i386at/grub_glue.c b/i386/i386at/grub_glue.c
+new file mode 100644
+index 0000000..68a4cb1
+--- /dev/null
++++ b/i386/i386at/grub_glue.c
+@@ -0,0 +1,67 @@
++/*
++ * Copyright (c) 2014 Free Software Foundation.
++ *
++ * 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/>.
++ */
++
++#include <kern/printf.h>
++#include <stdarg.h>
++#include <i386/vm_param.h>
++
++#include <grub/glue.h>
++#include <grub/acpi.h>
++
++#define GRUB_DEBUG 0
++
++void
++grub_real_dprintf (const char *file, const int line, const char *condition,
++                 const char *fmt, ...)
++{
++#if GRUB_DEBUG
++  va_list     listp;
++  va_start(listp, fmt);
++  vprintf (fmt, listp);
++  va_end(listp);
++#endif
++}
++
++void
++grub_millisleep (grub_uint32_t ms)
++{
++  /* Do nothing.  */
++}
++
++struct grub_acpi_rsdp_v20 *
++grub_acpi_get_rsdpv2 (void)
++{
++  return grub_machine_acpi_get_rsdpv2 ();
++}
++
++struct grub_acpi_rsdp_v10 *
++grub_acpi_get_rsdpv1 (void)
++{
++  return grub_machine_acpi_get_rsdpv1 ();
++}
++
++/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
++grub_uint8_t
++grub_byte_checksum (void *base, grub_size_t size)
++{
++  grub_uint8_t *ptr;
++  grub_uint8_t ret = 0;
++  for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
++       ptr++)
++    ret += *ptr;
++  return ret;
++}
+diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
+index 95752fa..6093a66 100644
+--- a/i386/i386at/model_dep.c
++++ b/i386/i386at/model_dep.c
+@@ -69,6 +69,7 @@
+ #include <i386at/int_init.h>
+ #include <i386at/kd.h>
+ #include <i386at/rtc.h>
++#include <i386at/acpihalt.h>
+ #ifdef        MACH_XEN
+ #include <xen/console.h>
+ #include <xen/store.h>
+@@ -231,6 +232,7 @@ void halt_all_cpus(boolean_t reboot)
+ #ifdef        MACH_HYP
+           hyp_halt();
+ #endif        /* MACH_HYP */
++          grub_acpi_halt();
+           printf("In tight loop: hit ctl-alt-del to reboot\n");
+           (void) spl0();
+       }
+commit 97447914d6dcc32ada4ee028e1e2bab262501316
+Author: Samuel Thibault <address@hidden>
+Date:   Sun Jul 6 18:48:45 2014 +0200
+
+    Document that io_map_cached leaks memory
+
+diff --git a/i386/grub/glue.h b/i386/grub/glue.h
+index e1c62eb..ae41014 100644
+--- a/i386/grub/glue.h
++++ b/i386/grub/glue.h
+@@ -26,6 +26,8 @@
+ #include <mach/mach_types.h>
+ #include <i386/vm_param.h>
+ 
++/* Warning: this leaks memory maps for now, do not use it yet for something
++ * else than Mach shutdown. */
+ vm_offset_t io_map_cached(vm_offset_t phys_addr, vm_size_t size);
+ 
+ #endif /* _GRUB_GLUE_H */
+diff --git a/i386/i386/io_map.c b/i386/i386/io_map.c
+index 03d7152..2c2aa72 100644
+--- a/i386/i386/io_map.c
++++ b/i386/i386/io_map.c
+@@ -66,6 +66,9 @@ io_map(
+  * This maps the all pages containing [PHYS_ADDR:PHYS_ADDR + SIZE].
+  * For contiguous requests to those pages will reuse the previously
+  * established mapping.
++ *
++ * Warning: this leaks memory maps for now, do not use it yet for something
++ * else than Mach shutdown.
+  */
+ vm_offset_t
+ io_map_cached(
+commit 859c342d11a2d018e7b220e955bbe1ba1940f02f
+Author: Samuel Thibault <address@hidden>
+Date:   Sun Jul 6 18:49:55 2014 +0200
+
+    Do not unmap page 0 when not needed
+    
+    Since we need it to access some BIOS information, e.g. at ACPI shutdown.  
When
+    the kernel VM is not starting at 0, there is already nothing mapped there 
in
+    user tasks, anyway.
+    
+    * i386/i386at/model_dep.c (machine_init) [VM_MIN_KERNEL_ADDRESS != 0]:
+    Do not call pmap_unmap_page_zero.
+    * i386/intel/pmap.c (pmap_unmap_page_zero): Warn that unmapping page
+    zero may break some BIOS functions.
+
+diff --git a/i386/i386at/acpi.c b/i386/i386at/acpi.c
+index ec8aeb1..986b3a2 100644
+--- a/i386/i386at/acpi.c
++++ b/i386/i386at/acpi.c
+@@ -55,8 +55,11 @@ grub_machine_acpi_get_rsdpv2 (void)
+   grub_uint8_t *ebda, *ptr;
+ 
+   grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
++  printf("ptr is %p\n", (* ((grub_uint16_t *) phystokv (0x40e))) << 4);
++  printf("len is %u\n", *( (grub_uint16_t *) phystokv ((* ((grub_uint16_t *) 
phystokv (0x40e))) << 4)));
+   ebda = (grub_uint8_t *) phystokv ((* ((grub_uint16_t *) phystokv (0x40e))) 
<< 4);
+   ebda_len = * (grub_uint16_t *) ebda;
++  printf("EBDA len %d\n", ebda_len);
+   if (! ebda_len)
+     return 0;
+   for (ptr = ebda; ptr < ebda + 0x400; ptr += 16)
+diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
+index 6093a66..209cfb1 100644
+--- a/i386/i386at/model_dep.c
++++ b/i386/i386at/model_dep.c
+@@ -180,10 +180,14 @@ void machine_init(void)
+       *(unsigned short *)phystokv(0x472) = 0x1234;
+ #endif        /* MACH_HYP */
+ 
++#if VM_MIN_KERNEL_ADDRESS == 0
+       /*
+        * Unmap page 0 to trap NULL references.
++       *
++       * Note that this breaks accessing some BIOS areas stored there.
+        */
+       pmap_unmap_page_zero();
++#endif
+ }
+ 
+ /* Conserve power on processor CPU.  */
+diff --git a/i386/intel/pmap.c b/i386/intel/pmap.c
+index 8a23a44..62b33cf 100644
+--- a/i386/intel/pmap.c
++++ b/i386/intel/pmap.c
+@@ -2835,6 +2835,7 @@ pmap_unmap_page_zero (void)
+ {
+   int *pte;
+ 
++  printf("Unmapping the zero page.  Some BIOS functions may not be working 
any more.\n");
+   pte = (int *) pmap_pte (kernel_pmap, 0);
+   if (!pte)
+     return;
diff --git a/debian/patches/git-xen-memory-clobber.patch 
b/debian/patches/git-xen-memory-clobber.patch
new file mode 100644
index 0000000..187b4dd
--- /dev/null
+++ b/debian/patches/git-xen-memory-clobber.patch
@@ -0,0 +1,21 @@
+commit dc1631b7dc508cb67fa6983007ddba3a2314d6bf
+Author: Samuel Thibault <address@hidden>
+Date:   Tue May 27 20:28:56 2014 +0200
+
+    Add missing memory clobber
+    
+    * i386/i386/xen.h (mb, rmb, wmb): Add memory clobber.
+
+diff --git a/i386/i386/xen.h b/i386/i386/xen.h
+index 5bdaf0b..638d671 100644
+--- a/i386/i386/xen.h
++++ b/i386/i386/xen.h
+@@ -33,7 +33,7 @@
+ 
+ /* TODO: this should be moved in appropriate non-Xen place.  */
+ #define barrier() __asm__ __volatile__ ("": : :"memory")
+-#define mb() __asm__ __volatile__("lock; addl $0,0(%esp)")
++#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)":::"memory")
+ #define rmb() mb()
+ #define wmb() mb()
+ MACH_INLINE unsigned long xchgl(volatile unsigned long *ptr, unsigned long x)
diff --git a/debian/patches/series b/debian/patches/series
index 33f607a..c8fa6d0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -20,3 +20,5 @@ git-device_translatable.patch
 git-device_translatable2.patch
 git-mach_debug.patch
 git-mach_debug2.patch
+git-halt.patch
+git-xen-memory-clobber.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/gnumach.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]