Compare commits

..
Author SHA1 Message Date
Simon Peter e7f405abb3 Reimport Simon Peter's devmapper 2013-10-26 18:54:36 +02:00
19 changed files with 639 additions and 245 deletions

No files matched your search

-18
View File
@@ -1,21 +1,3 @@
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
Consolidate cpuid code.
2013-10-26 Vladimir Serbinenko <phcoder@gmail.com>
Move cpuid code to cpuid.h and TSC code to tsc.c.
2013-10-26 Grégoire Sutre <gregoire.sutre@gmail.com>
* util/grub.d/00_header.in: Don't use LANG if it's not set.
2013-10-26 Grégoire Sutre <gregoire.sutre@gmail.com>
* util/grub-mkconfig.in: Replace $0 with $self.
* util/grub-reboot.in: Likewise.
* util/grub-set-default.in: Likewise.
2013-10-26 BVK Chaitanya <bvk.groups@gmail.com> 2013-10-26 BVK Chaitanya <bvk.groups@gmail.com>
* docs/osdetect.cfg: New file. * docs/osdetect.cfg: New file.
-1
View File
@@ -146,7 +146,6 @@ library = {
common = grub-core/partmap/sunpc.c; common = grub-core/partmap/sunpc.c;
common = grub-core/partmap/bsdlabel.c; common = grub-core/partmap/bsdlabel.c;
common = grub-core/partmap/dfly.c; common = grub-core/partmap/dfly.c;
common = grub-core/partmap/dasd.c;
common = grub-core/script/function.c; common = grub-core/script/function.c;
common = grub-core/script/lexer.c; common = grub-core/script/lexer.c;
common = grub-core/script/main.c; common = grub-core/script/main.c;
-4
View File
@@ -90,7 +90,6 @@ case "$target_cpu" in
i[[3456]]86) target_cpu=i386 ;; i[[3456]]86) target_cpu=i386 ;;
amd64) target_cpu=x86_64 ;; amd64) target_cpu=x86_64 ;;
sparc) target_cpu=sparc64 ;; sparc) target_cpu=sparc64 ;;
s390x) target_cpu=s390 ;;
mipsel|mips64el) mipsel|mips64el)
target_cpu=mipsel; target_cpu=mipsel;
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1"; machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1";
@@ -123,7 +122,6 @@ if test "x$with_platform" = x; then
mips-*) platform=arc ;; mips-*) platform=arc ;;
ia64-*) platform=efi ;; ia64-*) platform=efi ;;
arm-*) platform=uboot ;; arm-*) platform=uboot ;;
s390-* | s390x-*) platform=mainframe ;;
*) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
esac esac
else else
@@ -161,7 +159,6 @@ case "$target_cpu"-"$platform" in
mipsel-loongson) ;; mipsel-loongson) ;;
arm-uboot) ;; arm-uboot) ;;
arm-efi) ;; arm-efi) ;;
s390-mainframe) ;;
*-emu) ;; *-emu) ;;
*) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
esac esac
@@ -1334,7 +1331,6 @@ AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target
AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc])
AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
AM_CONDITIONAL([COND_s390_mainframe], [test x$target_cpu = xs390 -a x$platform = xmainframe])
AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel])
AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
+1 -2
View File
@@ -23,7 +23,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
"i386_multiboot", "i386_ieee1275", "x86_64_efi", "i386_multiboot", "i386_ieee1275", "x86_64_efi",
"mips_loongson", "sparc64_ieee1275", "mips_loongson", "sparc64_ieee1275",
"powerpc_ieee1275", "mips_arc", "ia64_efi", "powerpc_ieee1275", "mips_arc", "ia64_efi",
"mips_qemu_mips", "arm_uboot", "arm_efi", "s390_mainframe" ] "mips_qemu_mips", "arm_uboot", "arm_efi" ]
GROUPS = {} GROUPS = {}
@@ -37,7 +37,6 @@ GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
GROUPS["sparc64"] = [ "sparc64_ieee1275" ] GROUPS["sparc64"] = [ "sparc64_ieee1275" ]
GROUPS["powerpc"] = [ "powerpc_ieee1275" ] GROUPS["powerpc"] = [ "powerpc_ieee1275" ]
GROUPS["arm"] = [ "arm_uboot", "arm_efi" ] GROUPS["arm"] = [ "arm_uboot", "arm_efi" ]
GROUPS["s390"] = [ "s390_mainframe" ]
# Groups based on firmware # Groups based on firmware
GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ] GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
+5 -6
View File
@@ -78,7 +78,6 @@ kernel = {
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)'; mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)';
mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000';
s390_mainframe_ldflags = '-Wl,-Ttext,0x8000';
mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)'; mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)';
mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK'; mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK';
@@ -1738,11 +1737,6 @@ module = {
common = partmap/dfly.c; common = partmap/dfly.c;
}; };
module = {
name = part_dasd;
common = partmap/dasd.c;
};
module = { module = {
name = msdospart; name = msdospart;
common = parttool/msdospart.c; common = parttool/msdospart.c;
@@ -2146,3 +2140,8 @@ module = {
name = progress; name = progress;
common = lib/progress.c; common = lib/progress.c;
}; };
module = {
name = crypto_devmapper;
common = disk/devmapper.c;
};
+8 -3
View File
@@ -29,6 +29,11 @@
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
#define cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (num))
static const struct grub_arg_option options[] = static const struct grub_arg_option options[] =
{ {
/* TRANSLATORS: "(default)" at the end means that this option is used if /* TRANSLATORS: "(default)" at the end means that this option is used if
@@ -73,18 +78,18 @@ GRUB_MOD_INIT(cpuid)
goto done; goto done;
/* Check the highest input value for eax. */ /* Check the highest input value for eax. */
grub_cpuid (0, eax, ebx, ecx, edx); cpuid (0, eax, ebx, ecx, edx);
/* We only look at the first four characters. */ /* We only look at the first four characters. */
max_level = eax; max_level = eax;
if (max_level == 0) if (max_level == 0)
goto done; goto done;
grub_cpuid (0x80000000, eax, ebx, ecx, edx); cpuid (0x80000000, eax, ebx, ecx, edx);
ext_level = eax; ext_level = eax;
if (ext_level < 0x80000000) if (ext_level < 0x80000000)
goto done; goto done;
grub_cpuid (0x80000001, eax, ebx, ecx, edx); cpuid (0x80000001, eax, ebx, ecx, edx);
grub_cpuid_has_longmode = !!(edx & bit_LM); grub_cpuid_has_longmode = !!(edx & bit_LM);
done: done:
#endif #endif
+414
View File
@@ -0,0 +1,414 @@
/*
* devmapper.c - Device mapper (w/ crypto support)
*
* Copyright (C) 2007 Simon Peter <dn.tlp@gmx.net>
* Thanks to Raoul Boenisch <jkl345@gmx.net> for the initial idea.
*/
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,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/>.
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/disk.h>
#include <grub/crypto.h>
#define DEFAULT_HASH "ripemd160"
#define DEFAULT_CIPHER "aes-cbc"
#define MAX_KEYSIZE 64
#define MAX_PASSPHRASE 256
#define MIN(a, b) (a < b ? a : b)
struct grub_crypto
{
char *devname, *source_devname;
int has_partitions;
grub_crypto_cipher_handle_t cipher;
grub_disk_t srcdisk;
int keysize;
struct grub_crypto *next;
};
typedef struct grub_crypto *grub_crypto_t;
struct crypto_private
{
grub_crypto_t crypto;
grub_disk_t srcdisk;
};
typedef struct crypto_private *crypto_private_t;
static grub_crypto_t crypto_list = NULL;
/* Delete a registered crypto device. */
static grub_err_t
delete_crypto (const char *name)
{
grub_crypto_t dev, *prev;
/* Search for the device */
for (dev = crypto_list, prev = &crypto_list; dev;
prev = &dev->next, dev = dev->next)
if (grub_strcmp (dev->devname, name) == 0)
break;
if (!dev)
return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
/* Remove the device from the list */
*prev = dev->next;
grub_free (dev->devname);
grub_free (dev->source_devname);
grub_crypto_cipher_close (dev->cipher);
grub_free (dev);
return GRUB_ERR_NONE;
}
/* Hashes a passphrase into a key and stores it with cipher. */
static gcry_err_code_t
set_passphrase (grub_crypto_t dev, const gcry_md_spec_t *hashparams,
const char *passphrase)
{
grub_uint8_t hash[MAX_KEYSIZE * 2], *key = hash;
char *p;
unsigned int round, i, size = dev->keysize;
unsigned int len;
/* Need no passphrase if there's no key */
if (size == 0)
return GPG_ERR_INV_KEYLEN;
/* Hack to support the "none" hash */
if (hashparams)
len = hashparams->mdlen;
else
len = grub_strlen (passphrase);
if (size > MAX_KEYSIZE || len > MAX_KEYSIZE)
return GPG_ERR_INV_KEYLEN;
p = grub_malloc (grub_strlen (passphrase) + 2 + size / len);
if (!p)
return grub_errno;
for (round = 0; size; round++, key += len, size -= len)
{
/* hack from hashalot to avoid null bytes in key */
for (i = 0; i < round; i++)
p[i] = 'A';
grub_strcpy (p + i, passphrase);
if (len > size)
len = size;
grub_crypto_hash (hashparams, key, p, grub_strlen (p));
}
return grub_crypto_cipher_set_key (dev->cipher, hash, size);
}
/***** GRUB command line interface *****************************************/
static const struct grub_arg_option options[] = {
{"delete", 'd', 0, "delete the crypto device entry", 0, ARG_TYPE_NONE},
{"partitions", 'p', 0, "set that the device has partitions", 0,
ARG_TYPE_NONE},
{"cipher", 'c', 0, "set cipher (default=" DEFAULT_CIPHER ")", 0,
ARG_TYPE_STRING},
{"hash", 'h', 0, "set hash function (default=" DEFAULT_HASH ")", 0,
ARG_TYPE_STRING},
{"passphrase", 'P', 0, "set decryption passphrase", 0, ARG_TYPE_STRING},
{"keysize", 'k', 0, "set key size (default is cipher specific)", 0,
ARG_TYPE_INT},
{0, 0, 0, 0, 0, 0}
};
static grub_err_t
grub_cmd_devmap (grub_extcmd_t cmd, int argc, char **args)
{
grub_disk_t disk;
grub_crypto_t newdev;
const char *cipher, *hash;
const gcry_md_spec_t *hashparams;
grub_err_t err = GRUB_ERR_NONE;
char *passphrase = "";
/* char cmdphrase[MAX_PASSPHRASE]; */
const gcry_cipher_spec_t *ciph;
struct grub_arg_list *state = cmd->state;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Device name required");
/* Check whether delete is requested */
if (state[0].set)
return delete_crypto (args[0]);
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Source device name required");
/*** Create device is requested ***/
/* Choke on already existing devices */
for (newdev = crypto_list; newdev != NULL; newdev = newdev->next)
if (grub_strcmp (newdev->devname, args[0]) == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Device already exists");
/* Check whether source device can be opened */
disk = grub_disk_open (args[1]);
if (!disk)
return grub_errno;
grub_disk_close (disk);
/* Parse remaining options */
if (state[2].set)
cipher = state[2].arg;
else
cipher = DEFAULT_CIPHER;
if (state[3].set)
hash = state[3].arg;
else
hash = DEFAULT_HASH;
/* Create new device entry */
newdev = grub_malloc (sizeof (struct grub_crypto));
if (!newdev)
return grub_errno;
newdev->devname = grub_strdup (args[0]);
if (!newdev->devname)
{
grub_free (newdev);
return grub_errno;
}
newdev->source_devname = grub_strdup (args[1]);
if (!newdev->source_devname)
{
grub_free (newdev->devname);
grub_free (newdev);
return grub_errno;
}
newdev->has_partitions = state[1].set;
ciph = grub_crypto_lookup_cipher_by_name (cipher);
if (!ciph)
{
grub_free (newdev->source_devname);
grub_free (newdev->devname);
grub_free (newdev);
return grub_error (GRUB_ERR_CIPHER_NOT_FOUND, "Unknown cipher %s", hash);
}
newdev->cipher = grub_crypto_cipher_open (ciph);
if (!newdev->cipher)
{
grub_free (newdev->source_devname);
grub_free (newdev->devname);
grub_free (newdev);
return grub_errno;
}
hashparams = grub_crypto_lookup_md_by_name (hash);
if (!hashparams)
{
grub_free (newdev->source_devname);
grub_free (newdev->devname);
grub_free (newdev);
grub_crypto_cipher_close (newdev->cipher);
return grub_error (GRUB_ERR_CIPHER_NOT_FOUND, "Unknown digest %s", hash);
}
newdev->srcdisk = NULL;
if (state[5].set)
newdev->keysize = grub_strtoul (state[5].arg, NULL, 10);
else
newdev->keysize = 16;
/* Get passphrase */
if (state[4].set) /* Passphrase supplied on commandline */
passphrase = state[4].arg;
else
{
#if 1
return 0;
#else
if (grub_strcmp (cipher, "none"))
{
grub_cmdline_get ("Passphrase: ", cmdphrase, MAX_PASSPHRASE, '*',
0);
passphrase = cmdphrase;
}
#endif
}
err = set_passphrase (newdev, hashparams, passphrase);
if (err)
{
grub_crypto_cipher_close (newdev->cipher);
grub_free (newdev->source_devname);
grub_free (newdev->devname);
grub_free (newdev);
return err;
}
/* Add new entry to list and return */
newdev->next = crypto_list;
crypto_list = newdev;
/* Error conditions */
return GRUB_ERR_NONE;
}
/***** GRUB disk device interface ******************************************/
static int
grub_crypto_iterate (int (*hook) (const char *name))
{
grub_crypto_t i;
for (i = crypto_list; i != NULL; i = i->next)
if (hook (i->devname))
return 1;
return 0;
}
static grub_err_t
grub_crypto_open (const char *name, grub_disk_t disk)
{
grub_crypto_t dev;
crypto_private_t private;
for (dev = crypto_list; dev != NULL; dev = dev->next)
if (grub_strcmp (dev->devname, name) == 0)
break;
if (!dev)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
/* Setup crypto private structure */
if (!(private = grub_malloc (sizeof (struct crypto_private))))
return grub_errno;
private->crypto = dev;
/* Open underlying device */
private->srcdisk = grub_disk_open (dev->source_devname);
if (!private->srcdisk)
{
return grub_errno;
}
/* Populate requested disk */
disk->total_sectors = grub_disk_get_size (private->srcdisk);
disk->id = (int) dev;
disk->has_partitions = dev->has_partitions;
disk->data = private;
return 0;
}
static void
grub_crypto_close (grub_disk_t disk)
{
crypto_private_t private = (crypto_private_t) disk->data;
grub_disk_close (private->srcdisk);
grub_free (private);
}
static grub_err_t
grub_crypto_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
crypto_private_t private = (crypto_private_t) disk->data;
grub_err_t err;
grub_crypto_cipher_handle_t cipher = private->crypto->cipher;
grub_size_t i;
/* Read sectors from underlying disk */
err =
grub_disk_read (private->srcdisk, sector, 0,
size << GRUB_DISK_SECTOR_BITS, buf);
if (err)
return err;
/* Decrypt sectors */
for (i = 0; i < size; i++)
{
grub_disk_addr_t s = grub_cpu_to_le64 (sector + i);
grub_uint8_t iv[cipher->cipher->blocksize];
gcry_err_code_t gcry_err;
/* Set IV from raw sector number (plain mode) */
grub_memset (iv, 0, cipher->cipher->blocksize);
grub_memcpy (iv, &s,
MIN (sizeof (grub_disk_addr_t),
cipher->cipher->blocksize));
gcry_err = grub_crypto_cbc_decrypt (cipher,
buf + (i << GRUB_DISK_SECTOR_BITS),
buf + (i << GRUB_DISK_SECTOR_BITS),
GRUB_DISK_SECTOR_SIZE, iv);
if (gcry_err)
return grub_crypto_gcry_error (gcry_err);
}
return 0;
}
static grub_err_t
grub_crypto_write (grub_disk_t disk __attribute ((unused)),
grub_disk_addr_t sector __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return GRUB_ERR_NOT_IMPLEMENTED_YET;
}
static struct grub_disk_dev grub_crypto_dev = {
.name = "crypto",
.id = GRUB_DISK_DEVICE_DEVMAP_ID,
.iterate = grub_crypto_iterate,
.open = grub_crypto_open,
.close = grub_crypto_close,
.read = grub_crypto_read,
.write = grub_crypto_write,
.next = 0
};
/***** GRUB module (de-)initialization *************************************/
static grub_extcmd_t cmd;
GRUB_MOD_INIT (devmapper)
{
cmd = grub_register_extcmd ("devmap", grub_cmd_devmap, GRUB_COMMAND_FLAG_BOTH,
"devmap [OPTIONS...] [DEVICE] [SRC-DEV]",
"Map one device onto another (w/ cryptography support).",
options);
grub_disk_dev_register (&grub_crypto_dev);
}
GRUB_MOD_FINI (devmapper)
{
grub_unregister_extcmd (cmd);
grub_disk_dev_unregister (&grub_crypto_dev);
}
+34 -2
View File
@@ -18,10 +18,42 @@
#include <grub/efiemu/efiemu.h> #include <grub/efiemu/efiemu.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i386/cpuid.h>
#define cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (num))
#define bit_LM (1 << 29)
const char * const char *
grub_efiemu_get_default_core_name (void) grub_efiemu_get_default_core_name (void)
{ {
return grub_cpuid_has_longmode ? "efiemu64.o" : "efiemu32.o";
unsigned int eax, ebx, ecx, edx;
unsigned int max_level;
unsigned int ext_level;
/* See if we can use cpuid. */
asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
"pushl %0; popfl; pushfl; popl %0; popfl"
: "=&r" (eax), "=&r" (ebx)
: "i" (0x00200000));
if (((eax ^ ebx) & 0x00200000) == 0)
return "efiemu32.o";
/* Check the highest input value for eax. */
cpuid (0, eax, ebx, ecx, edx);
/* We only look at the first four characters. */
max_level = eax;
if (max_level == 0)
return "efiemu32.o";
cpuid (0x80000000, eax, ebx, ecx, edx);
ext_level = eax;
if (ext_level < 0x80000000)
return "efiemu32.o";
cpuid (0x80000001, eax, ebx, ecx, edx);
return (edx & bit_LM) ? "efiemu64.o" : "efiemu32.o";
} }
+1 -31
View File
@@ -24,7 +24,6 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/i386/tsc.h> #include <grub/i386/tsc.h>
#include <grub/i386/cpuid.h>
#include <grub/i386/pit.h> #include <grub/i386/pit.h>
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
@@ -36,35 +35,6 @@ static grub_uint64_t tsc_boot_time;
in 32-bit. */ in 32-bit. */
grub_uint32_t grub_tsc_rate; grub_uint32_t grub_tsc_rate;
/* Read the TSC value, which increments with each CPU clock cycle. */
static __inline grub_uint64_t
grub_get_tsc (void)
{
grub_uint32_t lo, hi;
grub_uint32_t a,b,c,d;
/* The CPUID instruction is a 'serializing' instruction, and
avoids out-of-order execution of the RDTSC instruction. */
grub_cpuid (0,a,b,c,d);
/* Read TSC value. We cannot use "=A", since this would use
%rax on x86_64. */
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
return (((grub_uint64_t) hi) << 32) | lo;
}
static __inline int
grub_cpu_is_tsc_supported (void)
{
grub_uint32_t a,b,c,d;
if (! grub_cpu_is_cpuid_supported ())
return 0;
grub_cpuid(1,a,b,c,d);
return (d & (1 << 4)) != 0;
}
static void static void
grub_pit_wait (grub_uint16_t tics) grub_pit_wait (grub_uint16_t tics)
{ {
@@ -93,7 +63,7 @@ grub_pit_wait (grub_uint16_t tics)
GRUB_PIT_SPEAKER_PORT); GRUB_PIT_SPEAKER_PORT);
} }
static grub_uint64_t grub_uint64_t
grub_tsc_get_time_ms (void) grub_tsc_get_time_ms (void)
{ {
grub_uint64_t a = grub_get_tsc () - tsc_boot_time; grub_uint64_t a = grub_get_tsc () - tsc_boot_time;
+47 -4
View File
@@ -25,7 +25,6 @@
#include <grub/loader.h> #include <grub/loader.h>
#include <grub/autoefi.h> #include <grub/autoefi.h>
#include <grub/i386/tsc.h> #include <grub/i386/tsc.h>
#include <grub/i386/cpuid.h>
#include <grub/efi/api.h> #include <grub/efi/api.h>
#include <grub/i386/pit.h> #include <grub/i386/pit.h>
#include <grub/misc.h> #include <grub/misc.h>
@@ -126,22 +125,66 @@ guessfsb (void)
{ {
const grub_uint64_t sane_value = 100000000; const grub_uint64_t sane_value = 100000000;
grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow; grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
grub_uint32_t a, b, d;
if (! grub_cpu_is_cpuid_supported ()) if (! grub_cpu_is_cpuid_supported ())
return sane_value; return sane_value;
grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]); #ifdef __APPLE__
asm volatile ("movl $0, %%eax\n"
#ifdef __x86_64__
"push %%rbx\n"
#else
"push %%ebx\n"
#endif
"cpuid\n"
#ifdef __x86_64__
"pop %%rbx\n"
#else
"pop %%ebx\n"
#endif
: "=a" (max_cpuid),
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
/* Only Intel for now is done. */
if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
return sane_value;
#else
asm volatile ("movl $0, %%eax\n"
"cpuid"
: "=a" (max_cpuid), "=b" (manufacturer[0]),
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
/* Only Intel for now is done. */ /* Only Intel for now is done. */
if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0) if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
return sane_value; return sane_value;
#endif
/* Check Speedstep. */ /* Check Speedstep. */
if (max_cpuid < 1) if (max_cpuid < 1)
return sane_value; return sane_value;
grub_cpuid (1, a, b, capabilities, d); #ifdef __APPLE__
asm volatile ("movl $1, %%eax\n"
#ifdef __x86_64__
"push %%rbx\n"
#else
"push %%ebx\n"
#endif
"cpuid\n"
#ifdef __x86_64__
"pop %%rbx\n"
#else
"pop %%ebx\n"
#endif
: "=c" (capabilities):
: "%rax", "%rdx");
#else
asm volatile ("movl $1, %%eax\n"
"cpuid"
: "=c" (capabilities):
: "%rax", "%rbx", "%rdx");
#endif
if (! (capabilities & (1 << 7))) if (! (capabilities & (1 << 7)))
return sane_value; return sane_value;
-106
View File
@@ -1,106 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2012 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/partition.h>
#include <grub/disk.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/dl.h>
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/err.h>
GRUB_MOD_LICENSE ("GPLv3+");
static struct grub_partition_map grub_dasd_partition_map;
struct addr
{
grub_uint16_t cyl;
grub_uint16_t head;
grub_uint8_t sec;
} __attribute__ ((packed));
struct anchor
{
grub_uint8_t unused1[4];
grub_uint8_t magic[4];
grub_uint8_t unused2[7];
struct addr vtoc_addr;
} __attribute__ ((packed));
/* VOL1 in EBCDIC. */
#define ANCHOR_MAGIC "\xe5\xd6\xd3\xf1"
struct grub_disk_addr_t
address_to_block (const struct addr *a)
{
return a->cyl * + a->head * + a->sec;
}
static grub_err_t
dasd_partition_map_iterate (grub_disk_t disk,
int (*hook) (grub_disk_t disk,
const grub_partition_t partition))
{
grub_err_t err;
grub_partition_t p;
struct anchor anchor;
err = grub_disk_read (disk, 2 * 8, 0, sizeof (anchor), &anchor);
if (err)
return err;
if (grub_memcmp (anchor.magic, ANCHOR_MAGIC, sizeof (ANCHOR_MAGIC) - 1) != 0)
return grub_error (GRUB_ERR_BAD_PART_TABLE,
"not a dasd partition table");
p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
if (! p)
return grub_errno;
p->partmap = &grub_dasd_partition_map;
p->start = 0x18 << 3;
p->len = disk->total_sectors - p->start;
p->number = 0;
if (hook (disk, p))
{
grub_free (p);
return GRUB_ERR_NONE;
}
grub_free (p);
return GRUB_ERR_NONE;
}
/* Partition map type. */
static struct grub_partition_map grub_dasd_partition_map =
{
.name = "dasd",
.iterate = dasd_partition_map_iterate,
};
GRUB_MOD_INIT(part_dasd)
{
grub_partition_map_register (&grub_dasd_partition_map);
}
GRUB_MOD_FINI(part_dasd)
{
grub_partition_map_unregister (&grub_dasd_partition_map);
}
+9 -4
View File
@@ -29,7 +29,7 @@
#include <grub/video.h> #include <grub/video.h>
#include <grub/i386/pc/int.h> #include <grub/i386/pc/int.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/cpu/cpuid.h> #include <grub/cpu/tsc.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@@ -58,6 +58,11 @@ real2pm (grub_vbe_farptr_t ptr)
+ ((unsigned long) ptr & 0x0000FFFF)); + ((unsigned long) ptr & 0x0000FFFF));
} }
#define cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (num))
#define rdmsr(num,a,d) \ #define rdmsr(num,a,d) \
asm volatile ("rdmsr" : "=a" (a), "=d" (d) : "c" (num)) asm volatile ("rdmsr" : "=a" (a), "=d" (d) : "c" (num))
@@ -131,7 +136,7 @@ grub_vbe_enable_mtrr (grub_uint8_t *base, grub_size_t size)
if (! grub_cpu_is_cpuid_supported ()) if (! grub_cpu_is_cpuid_supported ())
return; return;
grub_cpuid (1, eax, ebx, ecx, edx); cpuid (1, eax, ebx, ecx, edx);
features = edx; features = edx;
if (! (features & 0x00001000)) /* MTRR */ if (! (features & 0x00001000)) /* MTRR */
return; return;
@@ -142,11 +147,11 @@ grub_vbe_enable_mtrr (grub_uint8_t *base, grub_size_t size)
return; return;
var_mtrrs = (mtrrcap & 0xFF); var_mtrrs = (mtrrcap & 0xFF);
grub_cpuid (0x80000000, eax, ebx, ecx, edx); cpuid (0x80000000, eax, ebx, ecx, edx);
max_extended_cpuid = eax; max_extended_cpuid = eax;
if (max_extended_cpuid >= 0x80000008) if (max_extended_cpuid >= 0x80000008)
{ {
grub_cpuid (0x80000008, eax, ebx, ecx, edx); cpuid (0x80000008, eax, ebx, ecx, edx);
maxphyaddr = (eax & 0xFF); maxphyaddr = (eax & 0xFF);
} }
else else
+1
View File
@@ -48,6 +48,7 @@ enum grub_disk_dev_id
GRUB_DISK_DEVICE_PROCFS_ID, GRUB_DISK_DEVICE_PROCFS_ID,
GRUB_DISK_DEVICE_CBFSDISK_ID, GRUB_DISK_DEVICE_CBFSDISK_ID,
GRUB_DISK_DEVICE_UBOOTDISK_ID, GRUB_DISK_DEVICE_UBOOTDISK_ID,
GRUB_DISK_DEVICE_DEVMAP_ID
}; };
struct grub_disk; struct grub_disk;
-60
View File
@@ -21,64 +21,4 @@
extern unsigned char grub_cpuid_has_longmode; extern unsigned char grub_cpuid_has_longmode;
#ifdef __x86_64__
static __inline int
grub_cpu_is_cpuid_supported (void)
{
grub_uint64_t id_supported;
__asm__ ("pushfq\n\t"
"popq %%rax /* Get EFLAGS into EAX */\n\t"
"movq %%rax, %%rcx /* Save original flags in ECX */\n\t"
"xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t"
"pushq %%rax /* Store modified EFLAGS on stack */\n\t"
"popfq /* Replace current EFLAGS */\n\t"
"pushfq /* Read back the EFLAGS */\n\t"
"popq %%rax /* Get EFLAGS into EAX */\n\t"
"xorq %%rcx, %%rax /* Check if flag could be modified */\n\t"
: "=a" (id_supported)
: /* No inputs. */
: /* Clobbered: */ "%rcx");
return id_supported != 0;
}
#else
static __inline int
grub_cpu_is_cpuid_supported (void)
{
grub_uint32_t id_supported;
__asm__ ("pushfl\n\t"
"popl %%eax /* Get EFLAGS into EAX */\n\t"
"movl %%eax, %%ecx /* Save original flags in ECX */\n\t"
"xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t"
"pushl %%eax /* Store modified EFLAGS on stack */\n\t"
"popfl /* Replace current EFLAGS */\n\t"
"pushfl /* Read back the EFLAGS */\n\t"
"popl %%eax /* Get EFLAGS into EAX */\n\t"
"xorl %%ecx, %%eax /* Check if flag could be modified */\n\t"
: "=a" (id_supported)
: /* No inputs. */
: /* Clobbered: */ "%rcx");
return id_supported != 0;
}
#endif
#ifdef __PIC__
#define grub_cpuid(num,a,b,c,d) \
asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
: "0" (num))
#else
#define grub_cpuid(num,a,b,c,d) \
asm volatile ("cpuid" \
: "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
: "0" (num))
#endif
#endif #endif
+115
View File
@@ -21,7 +21,122 @@
#include <grub/types.h> #include <grub/types.h>
/* Read the TSC value, which increments with each CPU clock cycle. */
static __inline grub_uint64_t
grub_get_tsc (void)
{
grub_uint32_t lo, hi;
/* The CPUID instruction is a 'serializing' instruction, and
avoids out-of-order execution of the RDTSC instruction. */
#ifdef __APPLE__
__asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
#ifdef __x86_64__
"push %%rbx\n"
#else
"push %%ebx\n"
#endif
"cpuid\n"
#ifdef __x86_64__
"pop %%rbx\n"
#else
"pop %%ebx\n"
#endif
:::"%rax", "%rcx", "%rdx");
#else
__asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
"cpuid":::"%rax", "%rbx", "%rcx", "%rdx");
#endif
/* Read TSC value. We cannot use "=A", since this would use
%rax on x86_64. */
__asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi));
return (((grub_uint64_t) hi) << 32) | lo;
}
#ifdef __x86_64__
static __inline int
grub_cpu_is_cpuid_supported (void)
{
grub_uint64_t id_supported;
__asm__ ("pushfq\n\t"
"popq %%rax /* Get EFLAGS into EAX */\n\t"
"movq %%rax, %%rcx /* Save original flags in ECX */\n\t"
"xorq $0x200000, %%rax /* Flip ID bit in EFLAGS */\n\t"
"pushq %%rax /* Store modified EFLAGS on stack */\n\t"
"popfq /* Replace current EFLAGS */\n\t"
"pushfq /* Read back the EFLAGS */\n\t"
"popq %%rax /* Get EFLAGS into EAX */\n\t"
"xorq %%rcx, %%rax /* Check if flag could be modified */\n\t"
: "=a" (id_supported)
: /* No inputs. */
: /* Clobbered: */ "%rcx");
return id_supported != 0;
}
#else
static __inline int
grub_cpu_is_cpuid_supported (void)
{
grub_uint32_t id_supported;
__asm__ ("pushfl\n\t"
"popl %%eax /* Get EFLAGS into EAX */\n\t"
"movl %%eax, %%ecx /* Save original flags in ECX */\n\t"
"xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t"
"pushl %%eax /* Store modified EFLAGS on stack */\n\t"
"popfl /* Replace current EFLAGS */\n\t"
"pushfl /* Read back the EFLAGS */\n\t"
"popl %%eax /* Get EFLAGS into EAX */\n\t"
"xorl %%ecx, %%eax /* Check if flag could be modified */\n\t"
: "=a" (id_supported)
: /* No inputs. */
: /* Clobbered: */ "%rcx");
return id_supported != 0;
}
#endif
static __inline int
grub_cpu_is_tsc_supported (void)
{
if (! grub_cpu_is_cpuid_supported ())
return 0;
grub_uint32_t features;
#ifdef __APPLE__
__asm__ ("movl $1, %%eax\n\t"
#ifdef __x86_64__
"push %%rbx\n"
#else
"push %%ebx\n"
#endif
"cpuid\n"
#ifdef __x86_64__
"pop %%rbx\n"
#else
"pop %%ebx\n"
#endif
: "=d" (features)
: /* No inputs. */
: /* Clobbered: */ "%rax", "%rcx");
#else
__asm__ ("movl $1, %%eax\n\t"
"cpuid\n"
: "=d" (features)
: /* No inputs. */
: /* Clobbered: */ "%rax", "%rbx", "%rcx");
#endif
return (features & (1 << 4)) != 0;
}
void grub_tsc_init (void); void grub_tsc_init (void);
grub_uint64_t grub_tsc_get_time_ms (void);
/* In ms per 2^32 ticks. */ /* In ms per 2^32 ticks. */
extern grub_uint32_t EXPORT_VAR(grub_tsc_rate); extern grub_uint32_t EXPORT_VAR(grub_tsc_rate);
+1 -1
View File
@@ -65,7 +65,7 @@ argument () {
shift shift
if test $# -eq 0; then if test $# -eq 0; then
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
exit 1 exit 1
fi fi
echo $1 echo $1
+1 -1
View File
@@ -65,7 +65,7 @@ argument () {
shift shift
if test $# -eq 0; then if test $# -eq 0; then
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
exit 1 exit 1
fi fi
echo $1 echo $1
+1 -1
View File
@@ -63,7 +63,7 @@ argument () {
shift shift
if test $# -eq 0; then if test $# -eq 0; then
gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 gettext_printf "%s: option requires an argument -- \`%s'\n" "$0" "$opt" 1>&2
exit 1 exit 1
fi fi
echo $1 echo $1
+1 -1
View File
@@ -191,7 +191,7 @@ EOF
EOF EOF
# Gettext variables and module # Gettext variables and module
if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then if [ "x${LANG}" != "xC" ] ; then
cat << EOF cat << EOF
set locale_dir=\$prefix/locale set locale_dir=\$prefix/locale
set lang=${grub_lang} set lang=${grub_lang}