diff options
Diffstat (limited to 'debian/patches/acpihalt.patch')
-rw-r--r-- | debian/patches/acpihalt.patch | 2372 |
1 files changed, 2372 insertions, 0 deletions
diff --git a/debian/patches/acpihalt.patch b/debian/patches/acpihalt.patch new file mode 100644 index 0000000..17ff686 --- /dev/null +++ b/debian/patches/acpihalt.patch @@ -0,0 +1,2372 @@ +diff --git a/ddb/db_command.c b/ddb/db_command.c +index ebb13df..8171119 100644 +--- a/ddb/db_command.c ++++ b/ddb/db_command.c +@@ -363,6 +363,7 @@ struct db_command db_command_table[] = { + { "show", 0, 0, db_show_cmds }, + { "reset", db_reset_cpu, 0, 0 }, + { "reboot", db_reset_cpu, 0, 0 }, ++ { "halt", db_halt_cpu, 0, 0 }, + { (char *)0, } + }; + +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 <bruno@clisp.org>, 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/i386/db_interface.h b/i386/i386/db_interface.h +index 97ff5c7..8d7daea 100644 +--- a/i386/i386/db_interface.h ++++ b/i386/i386/db_interface.h +@@ -98,6 +98,8 @@ db_stack_trace_cmd( + const char *modif); + + extern void ++db_halt_cpu(void); ++extern void + db_reset_cpu(void); + + void +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); ++} +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/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 7d138be..6093a66 100644 +--- a/i386/i386at/model_dep.c ++++ b/i386/i386at/model_dep.c +@@ -69,6 +69,7 @@ + #include <i386at/kd.h> + #include <i386at/rtc.h> + #include <i386at/model_dep.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(); + } +@@ -243,6 +245,11 @@ void exit(int rc) + halt_all_cpus(0); + } + ++void db_halt_cpu(void) ++{ ++ halt_all_cpus(0); ++} ++ + void db_reset_cpu(void) + { + halt_all_cpus(1); |